mirror of
https://github.com/swc-project/swc.git
synced 2024-11-23 09:38:16 +03:00
feat(es/parser): Implement explicit resource management (#7322)
**Description:** - Add `UsingDecl`. - Add `UsingDecl` to `Decl`. - Rename `VarDeclOrPat` to `ForHead`. - Add `UsingDecl` to `ForHead`. - Implement parser for using declarations. **Related issue:** - #7316.
This commit is contained in:
parent
6432e1f5c5
commit
041b491466
@ -870,8 +870,8 @@ XPathExpression
|
||||
XPathResult
|
||||
XSLTProcessor
|
||||
__proto__
|
||||
_define_property
|
||||
_defineProperty
|
||||
_define_property
|
||||
_extends
|
||||
_toConsumableArray
|
||||
a
|
||||
@ -2374,6 +2374,7 @@ url
|
||||
use
|
||||
usemap
|
||||
user-select
|
||||
using
|
||||
values
|
||||
var
|
||||
vb
|
||||
|
@ -892,7 +892,8 @@ where
|
||||
Decl::TsInterface(_)
|
||||
| Decl::TsTypeAlias(_)
|
||||
| Decl::TsEnum(_)
|
||||
| Decl::TsModule(_) => continue,
|
||||
| Decl::TsModule(_)
|
||||
| Decl::Using(..) => continue,
|
||||
};
|
||||
|
||||
tracing::trace!(
|
||||
|
@ -540,6 +540,7 @@ fn mark(item: &mut ModuleItem, ctxt: SyntaxContext) {
|
||||
Decl::Class(ClassDecl { class: v, .. }) => v.span.ctxt = ctxt,
|
||||
Decl::Fn(FnDecl { function: v, .. }) => v.span.ctxt = ctxt,
|
||||
Decl::Var(v) => v.span.ctxt = ctxt,
|
||||
Decl::Using(u) => u.span.ctxt = ctxt,
|
||||
Decl::TsInterface(v) => v.span.ctxt = ctxt,
|
||||
Decl::TsTypeAlias(v) => v.span.ctxt = ctxt,
|
||||
Decl::TsEnum(v) => v.span.ctxt = ctxt,
|
||||
|
@ -22,6 +22,9 @@ pub enum Decl {
|
||||
Fn(FnDecl),
|
||||
#[tag("VariableDeclaration")]
|
||||
Var(Box<VarDecl>),
|
||||
#[tag("UsingDeclaration")]
|
||||
Using(Box<UsingDecl>),
|
||||
|
||||
#[tag("TsInterfaceDeclaration")]
|
||||
TsInterface(Box<TsInterfaceDecl>),
|
||||
#[tag("TsTypeAliasDeclaration")]
|
||||
@ -33,6 +36,7 @@ pub enum Decl {
|
||||
}
|
||||
|
||||
bridge_decl_from!(Box<VarDecl>, VarDecl);
|
||||
bridge_decl_from!(Box<UsingDecl>, UsingDecl);
|
||||
bridge_decl_from!(Box<TsInterfaceDecl>, TsInterfaceDecl);
|
||||
bridge_decl_from!(Box<TsTypeAliasDecl>, TsTypeAliasDecl);
|
||||
bridge_decl_from!(Box<TsEnumDecl>, TsEnumDecl);
|
||||
@ -166,3 +170,21 @@ impl Take for VarDeclarator {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[ast_node("UsingDeclaration")]
|
||||
#[derive(Eq, Hash, EqIgnoreSpan)]
|
||||
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||
pub struct UsingDecl {
|
||||
pub span: Span,
|
||||
|
||||
pub decls: Vec<VarDeclarator>,
|
||||
}
|
||||
|
||||
impl Take for UsingDecl {
|
||||
fn dummy() -> Self {
|
||||
Self {
|
||||
span: DUMMY_SP,
|
||||
decls: Take::dummy(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ pub use self::{
|
||||
AutoAccessor, Class, ClassMember, ClassMethod, ClassProp, Constructor, Decorator, Key,
|
||||
MethodKind, PrivateMethod, PrivateProp, StaticBlock,
|
||||
},
|
||||
decl::{ClassDecl, Decl, FnDecl, VarDecl, VarDeclKind, VarDeclarator},
|
||||
decl::{ClassDecl, Decl, FnDecl, UsingDecl, VarDecl, VarDeclKind, VarDeclarator},
|
||||
expr::{
|
||||
ArrayLit, ArrowExpr, AssignExpr, AwaitExpr, BinExpr, BlockStmtOrExpr, CallExpr, Callee,
|
||||
ClassExpr, CondExpr, Expr, ExprOrSpread, FnExpr, Import, MemberExpr, MemberProp,
|
||||
@ -54,8 +54,8 @@ pub use self::{
|
||||
source_map::{SourceMapperExt, SpanExt},
|
||||
stmt::{
|
||||
BlockStmt, BreakStmt, CatchClause, ContinueStmt, DebuggerStmt, DoWhileStmt, EmptyStmt,
|
||||
ExprStmt, ForInStmt, ForOfStmt, ForStmt, IfStmt, LabeledStmt, ReturnStmt, Stmt, SwitchCase,
|
||||
SwitchStmt, ThrowStmt, TryStmt, VarDeclOrExpr, VarDeclOrPat, WhileStmt, WithStmt,
|
||||
ExprStmt, ForHead, ForInStmt, ForOfStmt, ForStmt, IfStmt, LabeledStmt, ReturnStmt, Stmt,
|
||||
SwitchCase, SwitchStmt, ThrowStmt, TryStmt, VarDeclOrExpr, WhileStmt, WithStmt,
|
||||
},
|
||||
typescript::{
|
||||
Accessibility, TruePlusMinus, TsArrayType, TsAsExpr, TsCallSignatureDecl,
|
||||
|
@ -6,6 +6,7 @@ use crate::{
|
||||
expr::Expr,
|
||||
ident::Ident,
|
||||
pat::Pat,
|
||||
UsingDecl,
|
||||
};
|
||||
|
||||
/// Use when only block statements are allowed.
|
||||
@ -303,7 +304,7 @@ pub struct ForStmt {
|
||||
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||
pub struct ForInStmt {
|
||||
pub span: Span,
|
||||
pub left: VarDeclOrPat,
|
||||
pub left: ForHead,
|
||||
pub right: Box<Expr>,
|
||||
pub body: Box<Stmt>,
|
||||
}
|
||||
@ -320,7 +321,7 @@ pub struct ForOfStmt {
|
||||
/// for-await-of statements, e.g., `for await (const x of xs) {`
|
||||
#[cfg_attr(feature = "serde-impl", serde(default, rename = "await"))]
|
||||
pub is_await: bool,
|
||||
pub left: VarDeclOrPat,
|
||||
pub left: ForHead,
|
||||
pub right: Box<Expr>,
|
||||
pub body: Box<Stmt>,
|
||||
}
|
||||
@ -376,23 +377,27 @@ pub struct CatchClause {
|
||||
pub body: BlockStmt,
|
||||
}
|
||||
|
||||
/// A head for for-in and for-of loop.
|
||||
#[ast_node]
|
||||
#[derive(Eq, Hash, Is, EqIgnoreSpan)]
|
||||
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||
pub enum VarDeclOrPat {
|
||||
pub enum ForHead {
|
||||
#[tag("VariableDeclaration")]
|
||||
VarDecl(Box<VarDecl>),
|
||||
|
||||
#[tag("UsingDeclaration")]
|
||||
UsingDecl(Box<UsingDecl>),
|
||||
|
||||
#[tag("*")]
|
||||
Pat(Box<Pat>),
|
||||
}
|
||||
|
||||
bridge_from!(VarDeclOrPat, Box<VarDecl>, VarDecl);
|
||||
bridge_from!(VarDeclOrPat, Box<Pat>, Pat);
|
||||
bridge_from!(ForHead, Box<VarDecl>, VarDecl);
|
||||
bridge_from!(ForHead, Box<Pat>, Pat);
|
||||
|
||||
impl Take for VarDeclOrPat {
|
||||
impl Take for ForHead {
|
||||
fn dummy() -> Self {
|
||||
VarDeclOrPat::Pat(Take::dummy())
|
||||
ForHead::Pat(Take::dummy())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ where
|
||||
{
|
||||
#[emitter]
|
||||
fn emit_decl(&mut self, node: &Decl) -> Result {
|
||||
match *node {
|
||||
match node {
|
||||
Decl::Class(ref n) => emit!(n),
|
||||
Decl::Fn(ref n) => emit!(n),
|
||||
|
||||
@ -21,6 +21,7 @@ where
|
||||
formatting_semi!();
|
||||
srcmap!(n, false);
|
||||
}
|
||||
Decl::Using(n) => emit!(n),
|
||||
Decl::TsEnum(ref n) => emit!(n),
|
||||
Decl::TsInterface(ref n) => emit!(n),
|
||||
Decl::TsModule(ref n) => emit!(n),
|
||||
@ -33,6 +34,20 @@ where
|
||||
self.emit_class_decl_inner(node, false)?;
|
||||
}
|
||||
|
||||
#[emitter]
|
||||
fn emit_using_decl(&mut self, node: &UsingDecl) -> Result {
|
||||
self.emit_leading_comments_of_span(node.span(), false)?;
|
||||
|
||||
keyword!("using");
|
||||
space!();
|
||||
|
||||
self.emit_list(
|
||||
node.span,
|
||||
Some(&node.decls),
|
||||
ListFormat::VariableDeclarationList,
|
||||
)?;
|
||||
}
|
||||
|
||||
pub(super) fn emit_class_decl_inner(
|
||||
&mut self,
|
||||
node: &ClassDecl,
|
||||
|
@ -2676,10 +2676,11 @@ where
|
||||
}
|
||||
|
||||
#[emitter]
|
||||
fn emit_var_decl_or_pat(&mut self, node: &VarDeclOrPat) -> Result {
|
||||
match *node {
|
||||
VarDeclOrPat::Pat(ref n) => emit!(n),
|
||||
VarDeclOrPat::VarDecl(ref n) => emit!(n),
|
||||
fn emit_for_head(&mut self, node: &ForHead) -> Result {
|
||||
match node {
|
||||
ForHead::Pat(n) => emit!(n),
|
||||
ForHead::VarDecl(n) => emit!(n),
|
||||
ForHead::UsingDecl(n) => emit!(n),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,11 +4,12 @@ pub trait EndsWithAlphaNum {
|
||||
fn ends_with_alpha_num(&self) -> bool;
|
||||
}
|
||||
|
||||
impl EndsWithAlphaNum for VarDeclOrPat {
|
||||
impl EndsWithAlphaNum for ForHead {
|
||||
fn ends_with_alpha_num(&self) -> bool {
|
||||
match self {
|
||||
VarDeclOrPat::VarDecl(n) => n.ends_with_alpha_num(),
|
||||
VarDeclOrPat::Pat(n) => n.ends_with_alpha_num(),
|
||||
ForHead::VarDecl(n) => n.ends_with_alpha_num(),
|
||||
ForHead::Pat(n) => n.ends_with_alpha_num(),
|
||||
ForHead::UsingDecl(n) => n.ends_with_alpha_num(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -37,6 +38,18 @@ impl EndsWithAlphaNum for VarDecl {
|
||||
}
|
||||
}
|
||||
|
||||
impl EndsWithAlphaNum for UsingDecl {
|
||||
fn ends_with_alpha_num(&self) -> bool {
|
||||
match self.decls.last() {
|
||||
None => true,
|
||||
Some(d) => match d.init.as_deref() {
|
||||
Some(e) => e.ends_with_alpha_num(),
|
||||
None => d.name.ends_with_alpha_num(),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl EndsWithAlphaNum for Expr {
|
||||
fn ends_with_alpha_num(&self) -> bool {
|
||||
!matches!(
|
||||
@ -230,7 +243,8 @@ impl StartsWithAlphaNum for Decl {
|
||||
| Decl::TsEnum(..)
|
||||
| Decl::TsInterface(..)
|
||||
| Decl::TsModule(..)
|
||||
| Decl::TsTypeAlias(..) => true,
|
||||
| Decl::TsTypeAlias(..)
|
||||
| Decl::Using(..) => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -255,7 +255,7 @@ impl Visit for NoParamReassign {
|
||||
}
|
||||
|
||||
fn visit_for_of_stmt(&mut self, for_of_stmt: &ForOfStmt) {
|
||||
if let VarDeclOrPat::Pat(pat) = &for_of_stmt.left {
|
||||
if let ForHead::Pat(pat) = &for_of_stmt.left {
|
||||
self.check_pat(pat);
|
||||
}
|
||||
|
||||
@ -263,7 +263,7 @@ impl Visit for NoParamReassign {
|
||||
}
|
||||
|
||||
fn visit_for_in_stmt(&mut self, for_in_stmt: &ForInStmt) {
|
||||
if let VarDeclOrPat::Pat(pat) = &for_in_stmt.left {
|
||||
if let ForHead::Pat(pat) = &for_in_stmt.left {
|
||||
self.check_pat(pat);
|
||||
}
|
||||
|
||||
|
@ -563,6 +563,10 @@ where
|
||||
// Variable declarations are handled by other functions.
|
||||
}
|
||||
|
||||
Decl::Using(..) => {
|
||||
// TODO: Optimize
|
||||
}
|
||||
|
||||
Decl::TsInterface(_) | Decl::TsTypeAlias(_) | Decl::TsEnum(_) | Decl::TsModule(_) => {
|
||||
// Nothing to do. We might change this to unreachable!()
|
||||
}
|
||||
|
@ -355,7 +355,7 @@ impl Visit for VarWithOutInitCounter {
|
||||
n.visit_children_with(self);
|
||||
}
|
||||
|
||||
fn visit_var_decl_or_pat(&mut self, _: &VarDeclOrPat) {}
|
||||
fn visit_for_head(&mut self, _: &ForHead) {}
|
||||
}
|
||||
|
||||
/// Moves all variable without initializer.
|
||||
@ -425,7 +425,7 @@ impl VisitMut for VarMover {
|
||||
self.var_decl_kind = old;
|
||||
}
|
||||
|
||||
fn visit_mut_var_decl_or_pat(&mut self, _: &mut VarDeclOrPat) {}
|
||||
fn visit_mut_for_head(&mut self, _: &mut ForHead) {}
|
||||
|
||||
fn visit_mut_var_declarators(&mut self, d: &mut Vec<VarDeclarator>) {
|
||||
d.visit_mut_children_with(self);
|
||||
|
@ -1651,8 +1651,8 @@ impl Visit for Shower<'_> {
|
||||
n.visit_children_with(self)
|
||||
}
|
||||
|
||||
fn visit_var_decl_or_pat(&mut self, n: &VarDeclOrPat) {
|
||||
self.show("VarDeclOrPat", n);
|
||||
fn visit_for_head(&mut self, n: &ForHead) {
|
||||
self.show("ForHead", n);
|
||||
n.visit_children_with(self)
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,12 @@ pub enum SyntaxError {
|
||||
Eof,
|
||||
DeclNotAllowed,
|
||||
|
||||
UsingDeclNotAllowed,
|
||||
UsingDeclNotAllowedForForInLoop,
|
||||
UsingDeclNotEnabled,
|
||||
InvalidNameInUsingDecl,
|
||||
InitRequiredForUsingDecl,
|
||||
|
||||
PrivateNameInInterface,
|
||||
|
||||
InvalidSuperCall,
|
||||
@ -523,6 +529,19 @@ impl SyntaxError {
|
||||
"The operand of a delete operator must be a property reference.".into()
|
||||
}
|
||||
SyntaxError::DeclNotAllowed => "Declaration is not allowed".into(),
|
||||
SyntaxError::UsingDeclNotAllowed => "Using declaration is not allowed".into(),
|
||||
SyntaxError::UsingDeclNotAllowedForForInLoop => {
|
||||
"Using declaration is not allowed in for-in loop".into()
|
||||
}
|
||||
SyntaxError::UsingDeclNotEnabled => {
|
||||
"Using declaration is not enabled. Set jsc.parser.usingDecl to true".into()
|
||||
}
|
||||
SyntaxError::InvalidNameInUsingDecl => {
|
||||
"Using declaration only allows identifiers".into()
|
||||
}
|
||||
SyntaxError::InitRequiredForUsingDecl => {
|
||||
"Using declaration requires initializer".into()
|
||||
}
|
||||
SyntaxError::InvalidSuperCall => "Invalid `super()`".into(),
|
||||
SyntaxError::InvalidSuper => "Invalid access to super".into(),
|
||||
SyntaxError::InvalidSuperPrivateName => {
|
||||
|
@ -281,6 +281,13 @@ impl Syntax {
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn using_decl(&self) -> bool {
|
||||
match self {
|
||||
Syntax::Es(EsConfig { using_decl, .. }) => *using_decl,
|
||||
Syntax::Typescript(_) => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
|
||||
@ -345,6 +352,9 @@ pub struct EsConfig {
|
||||
|
||||
#[serde(default)]
|
||||
pub auto_accessors: bool,
|
||||
|
||||
#[serde(default)]
|
||||
pub using_decl: bool,
|
||||
}
|
||||
|
||||
/// Syntactic context.
|
||||
@ -403,6 +413,8 @@ pub struct Context {
|
||||
ignore_else_clause: bool,
|
||||
|
||||
disallow_conditional_types: bool,
|
||||
|
||||
allow_using_decl: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
|
@ -417,6 +417,9 @@ macro_rules! tok {
|
||||
("protected") => {
|
||||
crate::token::Token::Word(crate::token::Word::Ident(swc_atoms::js_word!("protected")))
|
||||
};
|
||||
("using") => {
|
||||
crate::token::Token::Word(crate::token::Word::Ident(swc_atoms::js_word!("using")))
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! token_including_semi {
|
||||
|
@ -1618,7 +1618,7 @@ impl<I: Tokens> Parser<I> {
|
||||
Ok(callee)
|
||||
}
|
||||
|
||||
pub(super) fn parse_expr_or_pat(&mut self) -> PResult<Box<Expr>> {
|
||||
pub(super) fn parse_for_head_prefix(&mut self) -> PResult<Box<Expr>> {
|
||||
self.parse_expr()
|
||||
}
|
||||
|
||||
|
@ -301,6 +301,13 @@ impl<'a, I: Tokens> Parser<I> {
|
||||
}
|
||||
}
|
||||
|
||||
tok!("using") if include_decl => {
|
||||
let v = self.parse_using_decl()?;
|
||||
if let Some(v) = v {
|
||||
return Ok(Stmt::Decl(Decl::Using(v)));
|
||||
}
|
||||
}
|
||||
|
||||
tok!("interface") => {
|
||||
if is_typescript
|
||||
&& peeked_is!(self, IdentName)
|
||||
@ -328,7 +335,11 @@ impl<'a, I: Tokens> Parser<I> {
|
||||
}
|
||||
|
||||
tok!('{') => {
|
||||
return self.parse_block(false).map(Stmt::Block);
|
||||
let ctx = Context {
|
||||
allow_using_decl: true,
|
||||
..self.ctx()
|
||||
};
|
||||
return self.with_ctx(ctx).parse_block(false).map(Stmt::Block);
|
||||
}
|
||||
|
||||
_ => {}
|
||||
@ -751,6 +762,70 @@ impl<'a, I: Tokens> Parser<I> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn parse_using_decl(&mut self) -> PResult<Option<Box<UsingDecl>>> {
|
||||
// using
|
||||
// reader = init()
|
||||
|
||||
// is two statements
|
||||
let _ = cur!(self, false);
|
||||
if self.input.has_linebreak_between_cur_and_peeked() {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
if !peeked_is!(self, BindingIdent) {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let start = cur_pos!(self);
|
||||
assert_and_bump!(self, "using");
|
||||
|
||||
let mut decls = vec![];
|
||||
let mut first = true;
|
||||
while first || eat!(self, ',') {
|
||||
if first {
|
||||
first = false;
|
||||
}
|
||||
|
||||
// Handle
|
||||
// var a,;
|
||||
//
|
||||
// NewLine is ok
|
||||
if is_exact!(self, ';') || eof!(self) {
|
||||
let span = self.input.prev_span();
|
||||
self.emit_err(span, SyntaxError::TS1009);
|
||||
break;
|
||||
}
|
||||
|
||||
decls.push(self.parse_var_declarator(false, VarDeclKind::Var)?);
|
||||
}
|
||||
|
||||
if !self.syntax().using_decl() {
|
||||
self.emit_err(span!(self, start), SyntaxError::UsingDeclNotEnabled);
|
||||
}
|
||||
|
||||
if !self.ctx().allow_using_decl {
|
||||
self.emit_err(span!(self, start), SyntaxError::UsingDeclNotAllowed);
|
||||
}
|
||||
|
||||
for decl in &decls {
|
||||
match decl.name {
|
||||
Pat::Ident(..) => {}
|
||||
_ => {
|
||||
self.emit_err(span!(self, start), SyntaxError::InvalidNameInUsingDecl);
|
||||
}
|
||||
}
|
||||
|
||||
if decl.init.is_none() {
|
||||
self.emit_err(span!(self, start), SyntaxError::InitRequiredForUsingDecl);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Some(Box::new(UsingDecl {
|
||||
span: span!(self, start),
|
||||
decls,
|
||||
})))
|
||||
}
|
||||
|
||||
pub(super) fn parse_var_stmt(&mut self, for_loop: bool) -> PResult<Box<VarDecl>> {
|
||||
let start = cur_pos!(self);
|
||||
let kind = match bump!(self) {
|
||||
@ -1024,6 +1099,7 @@ impl<'a, I: Tokens> Parser<I> {
|
||||
fn parse_labelled_stmt(&mut self, l: Ident) -> PResult<Stmt> {
|
||||
let ctx = Context {
|
||||
is_break_allowed: true,
|
||||
allow_using_decl: false,
|
||||
..self.ctx()
|
||||
};
|
||||
self.with_ctx(ctx).parse_with(|p| {
|
||||
@ -1094,7 +1170,7 @@ impl<'a, I: Tokens> Parser<I> {
|
||||
|
||||
let span = span!(self, start);
|
||||
Ok(match head {
|
||||
ForHead::For { init, test, update } => {
|
||||
TempForHead::For { init, test, update } => {
|
||||
if let Some(await_token) = await_token {
|
||||
syntax_error!(self, await_token, SyntaxError::AwaitForStmt);
|
||||
}
|
||||
@ -1107,7 +1183,7 @@ impl<'a, I: Tokens> Parser<I> {
|
||||
body,
|
||||
})
|
||||
}
|
||||
ForHead::ForIn { left, right } => {
|
||||
TempForHead::ForIn { left, right } => {
|
||||
if let Some(await_token) = await_token {
|
||||
syntax_error!(self, await_token, SyntaxError::AwaitForStmt);
|
||||
}
|
||||
@ -1119,7 +1195,7 @@ impl<'a, I: Tokens> Parser<I> {
|
||||
body,
|
||||
})
|
||||
}
|
||||
ForHead::ForOf { left, right } => Stmt::ForOf(ForOfStmt {
|
||||
TempForHead::ForOf { left, right } => Stmt::ForOf(ForOfStmt {
|
||||
span,
|
||||
is_await: await_token.is_some(),
|
||||
left,
|
||||
@ -1129,7 +1205,7 @@ impl<'a, I: Tokens> Parser<I> {
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_for_head(&mut self) -> PResult<ForHead> {
|
||||
fn parse_for_head(&mut self) -> PResult<TempForHead> {
|
||||
let strict = self.ctx().strict;
|
||||
|
||||
if is_one_of!(self, "const", "var")
|
||||
@ -1168,18 +1244,51 @@ impl<'a, I: Tokens> Parser<I> {
|
||||
}
|
||||
}
|
||||
|
||||
return self.parse_for_each_head(VarDeclOrPat::VarDecl(decl));
|
||||
return self.parse_for_each_head(ForHead::VarDecl(decl));
|
||||
}
|
||||
|
||||
expect_exact!(self, ';');
|
||||
return self.parse_normal_for_head(Some(VarDeclOrExpr::VarDecl(decl)));
|
||||
}
|
||||
|
||||
let init = if eat_exact!(self, ';') {
|
||||
if eat_exact!(self, ';') {
|
||||
return self.parse_normal_for_head(None);
|
||||
} else {
|
||||
self.include_in_expr(false).parse_expr_or_pat()?
|
||||
};
|
||||
}
|
||||
|
||||
let start = cur_pos!(self);
|
||||
let init = self.include_in_expr(false).parse_for_head_prefix()?;
|
||||
|
||||
let is_using_decl = self.input.syntax().using_decl()
|
||||
&& match *init {
|
||||
Expr::Ident(Ident {
|
||||
sym: js_word!("using"),
|
||||
..
|
||||
}) => {
|
||||
is!(self, BindingIdent)
|
||||
&& !is!(self, "of")
|
||||
&& (peeked_is!(self, "of") || peeked_is!(self, "in"))
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
|
||||
if is_using_decl {
|
||||
let name = self.parse_binding_ident()?;
|
||||
let decl = VarDeclarator {
|
||||
name: Pat::Ident(name),
|
||||
span: span!(self, start),
|
||||
init: None,
|
||||
definite: false,
|
||||
};
|
||||
|
||||
let pat = Box::new(UsingDecl {
|
||||
span: span!(self, start),
|
||||
decls: vec![decl],
|
||||
});
|
||||
|
||||
cur!(self, true)?;
|
||||
|
||||
return self.parse_for_each_head(ForHead::UsingDecl(pat));
|
||||
}
|
||||
|
||||
// for (a of b)
|
||||
if is_one_of!(self, "of", "in") {
|
||||
@ -1196,7 +1305,7 @@ impl<'a, I: Tokens> Parser<I> {
|
||||
}
|
||||
}
|
||||
|
||||
return self.parse_for_each_head(VarDeclOrPat::Pat(Box::new(pat)));
|
||||
return self.parse_for_each_head(ForHead::Pat(Box::new(pat)));
|
||||
}
|
||||
|
||||
expect_exact!(self, ';');
|
||||
@ -1205,18 +1314,22 @@ impl<'a, I: Tokens> Parser<I> {
|
||||
self.parse_normal_for_head(Some(VarDeclOrExpr::Expr(init)))
|
||||
}
|
||||
|
||||
fn parse_for_each_head(&mut self, left: VarDeclOrPat) -> PResult<ForHead> {
|
||||
let of = bump!(self) == tok!("of");
|
||||
if of {
|
||||
fn parse_for_each_head(&mut self, left: ForHead) -> PResult<TempForHead> {
|
||||
let is_of = bump!(self) == tok!("of");
|
||||
if is_of {
|
||||
let right = self.include_in_expr(true).parse_assignment_expr()?;
|
||||
Ok(ForHead::ForOf { left, right })
|
||||
Ok(TempForHead::ForOf { left, right })
|
||||
} else {
|
||||
if let ForHead::UsingDecl(d) = &left {
|
||||
self.emit_err(d.span, SyntaxError::UsingDeclNotAllowedForForInLoop)
|
||||
}
|
||||
|
||||
let right = self.include_in_expr(true).parse_expr()?;
|
||||
Ok(ForHead::ForIn { left, right })
|
||||
Ok(TempForHead::ForIn { left, right })
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_normal_for_head(&mut self, init: Option<VarDeclOrExpr>) -> PResult<ForHead> {
|
||||
fn parse_normal_for_head(&mut self, init: Option<VarDeclOrExpr>) -> PResult<TempForHead> {
|
||||
let test = if eat_exact!(self, ';') {
|
||||
None
|
||||
} else {
|
||||
@ -1231,23 +1344,23 @@ impl<'a, I: Tokens> Parser<I> {
|
||||
self.include_in_expr(true).parse_expr().map(Some)?
|
||||
};
|
||||
|
||||
Ok(ForHead::For { init, test, update })
|
||||
Ok(TempForHead::For { init, test, update })
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::enum_variant_names)]
|
||||
enum ForHead {
|
||||
enum TempForHead {
|
||||
For {
|
||||
init: Option<VarDeclOrExpr>,
|
||||
test: Option<Box<Expr>>,
|
||||
update: Option<Box<Expr>>,
|
||||
},
|
||||
ForIn {
|
||||
left: VarDeclOrPat,
|
||||
left: ForHead,
|
||||
right: Box<Expr>,
|
||||
},
|
||||
ForOf {
|
||||
left: VarDeclOrPat,
|
||||
left: ForHead,
|
||||
right: Box<Expr>,
|
||||
},
|
||||
}
|
||||
@ -1417,7 +1530,7 @@ mod tests {
|
||||
Stmt::ForOf(ForOfStmt {
|
||||
span,
|
||||
is_await: true,
|
||||
left: VarDeclOrPat::VarDecl(Box::new(VarDecl {
|
||||
left: ForHead::VarDecl(Box::new(VarDecl {
|
||||
span,
|
||||
kind: VarDeclKind::Const,
|
||||
decls: vec![VarDeclarator {
|
||||
@ -1894,14 +2007,14 @@ export default function waitUntil(callback, options = {}) {
|
||||
assert!(trailing.borrow().is_empty());
|
||||
assert_eq!(leading.borrow().len(), 1);
|
||||
}
|
||||
fn parse_for_head(str: &'static str) -> ForHead {
|
||||
fn parse_for_head(str: &'static str) -> TempForHead {
|
||||
test_parser(str, Syntax::default(), |p| p.parse_for_head())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn for_array_binding_pattern() {
|
||||
match parse_for_head("let [, , t] = simple_array; t < 10; t++") {
|
||||
ForHead::For { init: Some(v), .. } => assert_eq_ignore_span!(
|
||||
TempForHead::For { init: Some(v), .. } => assert_eq_ignore_span!(
|
||||
v,
|
||||
VarDeclOrExpr::VarDecl(Box::new(VarDecl {
|
||||
span,
|
||||
@ -1933,7 +2046,7 @@ export default function waitUntil(callback, options = {}) {
|
||||
#[test]
|
||||
fn for_object_binding_pattern() {
|
||||
match parse_for_head("let {num} = obj; num < 11; num++") {
|
||||
ForHead::For { init: Some(v), .. } => assert_eq_ignore_span!(
|
||||
TempForHead::For { init: Some(v), .. } => assert_eq_ignore_span!(
|
||||
v,
|
||||
VarDeclOrExpr::VarDecl(Box::new(VarDecl {
|
||||
span,
|
||||
|
@ -2328,17 +2328,8 @@ impl<I: Tokens> Parser<I> {
|
||||
match &*expr.sym {
|
||||
"declare" => {
|
||||
let decl = self.try_parse_ts_declare(start, decorators)?;
|
||||
if let Some(mut decl) = decl {
|
||||
match &mut decl {
|
||||
Decl::Class(ClassDecl { declare, .. })
|
||||
| Decl::Fn(FnDecl { declare, .. }) => *declare = true,
|
||||
Decl::Var(v) => v.declare = true,
|
||||
Decl::TsInterface(v) => v.declare = true,
|
||||
Decl::TsTypeAlias(v) => v.declare = true,
|
||||
Decl::TsEnum(v) => v.declare = true,
|
||||
Decl::TsModule(v) => v.declare = true,
|
||||
}
|
||||
Ok(Some(decl))
|
||||
if let Some(decl) = decl {
|
||||
Ok(Some(make_decl_declare(decl)))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
@ -2824,6 +2815,7 @@ fn make_decl_declare(mut decl: Decl) -> Decl {
|
||||
Decl::TsTypeAlias(ref mut a) => a.declare = true,
|
||||
Decl::TsEnum(ref mut e) => e.declare = true,
|
||||
Decl::TsModule(ref mut m) => m.declare = true,
|
||||
Decl::Using(..) => unreachable!("Using is not a valid declaration for `declare` keyword"),
|
||||
}
|
||||
|
||||
decl
|
||||
|
@ -47,6 +47,7 @@ where
|
||||
} else {
|
||||
::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsConfig {
|
||||
jsx: is_jsx,
|
||||
using_decl: true,
|
||||
..Default::default()
|
||||
})
|
||||
};
|
||||
@ -64,6 +65,7 @@ where
|
||||
|
||||
#[cfg(feature = "verify")]
|
||||
#[testing::fixture("tests/errors/**/*.js")]
|
||||
#[testing::fixture("tests/errors/**/*.mjs")]
|
||||
#[testing::fixture("tests/errors/**/*.ts")]
|
||||
#[testing::fixture("tests/errors/**/*.tsx")]
|
||||
fn error(entry: PathBuf) {
|
||||
|
@ -0,0 +1 @@
|
||||
for await (using of of of);
|
@ -0,0 +1 @@
|
||||
for (using of of of);
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
using f, f = foo();
|
||||
}
|
||||
{
|
||||
using g = foo();
|
||||
using g = foo();
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
|
||||
x Using declaration requires initializer
|
||||
,-[$DIR/tests/errors/explicit-resource-management/invalid-duplicate-using-bindings/input.js:1:1]
|
||||
1 | {
|
||||
2 | using f, f = foo();
|
||||
: ^^^^^^^^^^^^^^^^^^
|
||||
3 | }
|
||||
`----
|
@ -0,0 +1 @@
|
||||
for (using foo in {});
|
@ -0,0 +1,6 @@
|
||||
|
||||
x Using declaration is not allowed in for-in loop
|
||||
,-[$DIR/tests/errors/explicit-resource-management/invalid-for-using-binding-in/input.js:1:1]
|
||||
1 | for (using foo in {});
|
||||
: ^^^^^^^^^
|
||||
`----
|
@ -0,0 +1 @@
|
||||
for (using of in []);
|
@ -0,0 +1,6 @@
|
||||
|
||||
x Expression expected
|
||||
,-[$DIR/tests/errors/explicit-resource-management/invalid-for-using-binding-of-in/input.js:1:1]
|
||||
1 | for (using of in []);
|
||||
: ^^
|
||||
`----
|
@ -0,0 +1,8 @@
|
||||
{
|
||||
while (1) using a;
|
||||
for (;;) using b;
|
||||
do using c; while (1);
|
||||
if (1) using d;
|
||||
with (1) using e;
|
||||
label: using f;
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
|
||||
x Expected ';', '}' or <eof>
|
||||
,-[$DIR/tests/errors/explicit-resource-management/invalid-in-single-statement-context/input.js:1:1]
|
||||
1 | {
|
||||
2 | while (1) using a;
|
||||
: ^^|^^ ^
|
||||
: `-- This is the expression part of an expression statement
|
||||
3 | for (;;) using b;
|
||||
`----
|
@ -0,0 +1,3 @@
|
||||
{
|
||||
label: using x = bar();
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
|
||||
x Expected ';', '}' or <eof>
|
||||
,-[$DIR/tests/errors/explicit-resource-management/invalid-labeled-using-binding/input.js:1:1]
|
||||
1 | {
|
||||
2 | label: using x = bar();
|
||||
: ^^|^^ ^
|
||||
: `-- This is the expression part of an expression statement
|
||||
3 | }
|
||||
`----
|
@ -0,0 +1 @@
|
||||
label: using x = bar();
|
@ -0,0 +1,7 @@
|
||||
|
||||
x Expected ';', '}' or <eof>
|
||||
,-[$DIR/tests/errors/explicit-resource-management/invalid-script-top-level-labeled-using-binding/input.js:1:1]
|
||||
1 | label: using x = bar();
|
||||
: ^^|^^ ^
|
||||
: `-- This is the expression part of an expression statement
|
||||
`----
|
@ -0,0 +1 @@
|
||||
using x = bar();
|
@ -0,0 +1,6 @@
|
||||
|
||||
x Using declaration is not allowed
|
||||
,-[$DIR/tests/errors/explicit-resource-management/invalid-script-top-level-using-binding/input.js:1:1]
|
||||
1 | using x = bar();
|
||||
: ^^^^^^^^^^^^^^^
|
||||
`----
|
@ -0,0 +1,12 @@
|
||||
{
|
||||
using await = h();
|
||||
}
|
||||
{
|
||||
using \u0061wait = h();
|
||||
}
|
||||
{
|
||||
using x, await = h();
|
||||
}
|
||||
{
|
||||
for (using await of []);
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
|
||||
x Expected ';', '}' or <eof>
|
||||
,-[$DIR/tests/errors/explicit-resource-management/invalid-using-binding-await-module/input.js:1:1]
|
||||
1 | {
|
||||
2 | using await = h();
|
||||
: ^^|^^ ^^^^^
|
||||
: `-- This is the expression part of an expression statement
|
||||
3 | }
|
||||
`----
|
@ -0,0 +1,12 @@
|
||||
{
|
||||
using await = h();
|
||||
}
|
||||
{
|
||||
using \u0061wait = h();
|
||||
}
|
||||
{
|
||||
using x, await = h();
|
||||
}
|
||||
{
|
||||
for (using await of []);
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
|
||||
x Expected ';', '}' or <eof>
|
||||
,-[$DIR/tests/errors/explicit-resource-management/invalid-using-binding-await-script/input.js:1:1]
|
||||
1 | {
|
||||
2 | using await = h();
|
||||
: ^^|^^ ^^^^^
|
||||
: `-- This is the expression part of an expression statement
|
||||
3 | }
|
||||
`----
|
@ -0,0 +1,3 @@
|
||||
{
|
||||
using let = h();
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
|
||||
x Expected ';', '}' or <eof>
|
||||
,-[$DIR/tests/errors/explicit-resource-management/invalid-using-binding-let/input.js:1:1]
|
||||
1 | {
|
||||
2 | using let = h();
|
||||
: ^^|^^ ^^^
|
||||
: `-- This is the expression part of an expression statement
|
||||
3 | }
|
||||
`----
|
@ -0,0 +1,3 @@
|
||||
{
|
||||
using { foo } = f();
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
|
||||
x Expected ';', '}' or <eof>
|
||||
,-[$DIR/tests/errors/explicit-resource-management/invalid-using-binding-pattern-declaration/input.js:1:1]
|
||||
1 | {
|
||||
2 | using { foo } = f();
|
||||
: ^^|^^ ^
|
||||
: `-- This is the expression part of an expression statement
|
||||
3 | }
|
||||
`----
|
@ -0,0 +1,3 @@
|
||||
{
|
||||
for (using { qux } of h());
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
|
||||
x Expected ';', got '{'
|
||||
,-[$DIR/tests/errors/explicit-resource-management/invalid-using-binding-pattern-for-lhs/input.js:1:1]
|
||||
1 | {
|
||||
2 | for (using { qux } of h());
|
||||
: ^
|
||||
3 | }
|
||||
`----
|
@ -8,7 +8,7 @@ use std::{
|
||||
|
||||
use swc_common::{comments::SingleThreadedComments, FileName};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_parser::{lexer::Lexer, PResult, Parser, Syntax};
|
||||
use swc_ecma_parser::{lexer::Lexer, EsConfig, PResult, Parser, Syntax};
|
||||
use swc_ecma_visit::FoldWith;
|
||||
use testing::StdErr;
|
||||
|
||||
@ -90,7 +90,10 @@ where
|
||||
.unwrap_or_else(|e| panic!("failed to load {}: {}", file_name.display(), e));
|
||||
|
||||
let lexer = Lexer::new(
|
||||
Syntax::Es(Default::default()),
|
||||
Syntax::Es(EsConfig {
|
||||
using_decl: true,
|
||||
..Default::default()
|
||||
}),
|
||||
EsVersion::Es2015,
|
||||
(&*fm).into(),
|
||||
Some(&comments),
|
||||
|
@ -0,0 +1 @@
|
||||
for (using o\u0066 of of);
|
@ -0,0 +1 @@
|
||||
for await (using \u006ff of of);
|
@ -0,0 +1 @@
|
||||
using (x);
|
@ -0,0 +1,53 @@
|
||||
{
|
||||
"type": "Script",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 11,
|
||||
"ctxt": 0
|
||||
},
|
||||
"body": [
|
||||
{
|
||||
"type": "ExpressionStatement",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 11,
|
||||
"ctxt": 0
|
||||
},
|
||||
"expression": {
|
||||
"type": "CallExpression",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 10,
|
||||
"ctxt": 0
|
||||
},
|
||||
"callee": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 6,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "using",
|
||||
"optional": false
|
||||
},
|
||||
"arguments": [
|
||||
{
|
||||
"spread": null,
|
||||
"expression": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 8,
|
||||
"end": 9,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "x",
|
||||
"optional": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"typeArguments": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"interpreter": null
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
using [x] = 0;
|
||||
for (using [x] of []);
|
@ -0,0 +1,136 @@
|
||||
{
|
||||
"type": "Script",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 38,
|
||||
"ctxt": 0
|
||||
},
|
||||
"body": [
|
||||
{
|
||||
"type": "ExpressionStatement",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 15,
|
||||
"ctxt": 0
|
||||
},
|
||||
"expression": {
|
||||
"type": "AssignmentExpression",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 14,
|
||||
"ctxt": 0
|
||||
},
|
||||
"operator": "=",
|
||||
"left": {
|
||||
"type": "MemberExpression",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 10,
|
||||
"ctxt": 0
|
||||
},
|
||||
"object": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 6,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "using",
|
||||
"optional": false
|
||||
},
|
||||
"property": {
|
||||
"type": "Computed",
|
||||
"span": {
|
||||
"start": 7,
|
||||
"end": 10,
|
||||
"ctxt": 0
|
||||
},
|
||||
"expression": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 8,
|
||||
"end": 9,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "x",
|
||||
"optional": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
"type": "NumericLiteral",
|
||||
"span": {
|
||||
"start": 13,
|
||||
"end": 14,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": 0.0,
|
||||
"raw": "0"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "ForOfStatement",
|
||||
"span": {
|
||||
"start": 16,
|
||||
"end": 38,
|
||||
"ctxt": 0
|
||||
},
|
||||
"await": false,
|
||||
"left": {
|
||||
"type": "MemberExpression",
|
||||
"span": {
|
||||
"start": 21,
|
||||
"end": 30,
|
||||
"ctxt": 0
|
||||
},
|
||||
"object": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 21,
|
||||
"end": 26,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "using",
|
||||
"optional": false
|
||||
},
|
||||
"property": {
|
||||
"type": "Computed",
|
||||
"span": {
|
||||
"start": 27,
|
||||
"end": 30,
|
||||
"ctxt": 0
|
||||
},
|
||||
"expression": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 28,
|
||||
"end": 29,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "x",
|
||||
"optional": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
"type": "ArrayExpression",
|
||||
"span": {
|
||||
"start": 34,
|
||||
"end": 36,
|
||||
"ctxt": 0
|
||||
},
|
||||
"elements": []
|
||||
},
|
||||
"body": {
|
||||
"type": "EmptyStatement",
|
||||
"span": {
|
||||
"start": 37,
|
||||
"end": 38,
|
||||
"ctxt": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"interpreter": null
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
using [x] = 0;
|
||||
for (using [x] of []);
|
@ -0,0 +1,136 @@
|
||||
{
|
||||
"type": "Script",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 38,
|
||||
"ctxt": 0
|
||||
},
|
||||
"body": [
|
||||
{
|
||||
"type": "ExpressionStatement",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 15,
|
||||
"ctxt": 0
|
||||
},
|
||||
"expression": {
|
||||
"type": "AssignmentExpression",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 14,
|
||||
"ctxt": 0
|
||||
},
|
||||
"operator": "=",
|
||||
"left": {
|
||||
"type": "MemberExpression",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 10,
|
||||
"ctxt": 0
|
||||
},
|
||||
"object": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 6,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "using",
|
||||
"optional": false
|
||||
},
|
||||
"property": {
|
||||
"type": "Computed",
|
||||
"span": {
|
||||
"start": 7,
|
||||
"end": 10,
|
||||
"ctxt": 0
|
||||
},
|
||||
"expression": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 8,
|
||||
"end": 9,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "x",
|
||||
"optional": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
"type": "NumericLiteral",
|
||||
"span": {
|
||||
"start": 13,
|
||||
"end": 14,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": 0.0,
|
||||
"raw": "0"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "ForOfStatement",
|
||||
"span": {
|
||||
"start": 16,
|
||||
"end": 38,
|
||||
"ctxt": 0
|
||||
},
|
||||
"await": false,
|
||||
"left": {
|
||||
"type": "MemberExpression",
|
||||
"span": {
|
||||
"start": 21,
|
||||
"end": 30,
|
||||
"ctxt": 0
|
||||
},
|
||||
"object": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 21,
|
||||
"end": 26,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "using",
|
||||
"optional": false
|
||||
},
|
||||
"property": {
|
||||
"type": "Computed",
|
||||
"span": {
|
||||
"start": 27,
|
||||
"end": 30,
|
||||
"ctxt": 0
|
||||
},
|
||||
"expression": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 28,
|
||||
"end": 29,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "x",
|
||||
"optional": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
"type": "ArrayExpression",
|
||||
"span": {
|
||||
"start": 34,
|
||||
"end": 36,
|
||||
"ctxt": 0
|
||||
},
|
||||
"elements": []
|
||||
},
|
||||
"body": {
|
||||
"type": "EmptyStatement",
|
||||
"span": {
|
||||
"start": 37,
|
||||
"end": 38,
|
||||
"ctxt": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"interpreter": null
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
using
|
||||
reader = getReader()
|
@ -0,0 +1,77 @@
|
||||
{
|
||||
"type": "Script",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 27,
|
||||
"ctxt": 0
|
||||
},
|
||||
"body": [
|
||||
{
|
||||
"type": "ExpressionStatement",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 6,
|
||||
"ctxt": 0
|
||||
},
|
||||
"expression": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 6,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "using",
|
||||
"optional": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "ExpressionStatement",
|
||||
"span": {
|
||||
"start": 7,
|
||||
"end": 27,
|
||||
"ctxt": 0
|
||||
},
|
||||
"expression": {
|
||||
"type": "AssignmentExpression",
|
||||
"span": {
|
||||
"start": 7,
|
||||
"end": 27,
|
||||
"ctxt": 0
|
||||
},
|
||||
"operator": "=",
|
||||
"left": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 7,
|
||||
"end": 13,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "reader",
|
||||
"optional": false,
|
||||
"typeAnnotation": null
|
||||
},
|
||||
"right": {
|
||||
"type": "CallExpression",
|
||||
"span": {
|
||||
"start": 16,
|
||||
"end": 27,
|
||||
"ctxt": 0
|
||||
},
|
||||
"callee": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 16,
|
||||
"end": 25,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "getReader",
|
||||
"optional": false
|
||||
},
|
||||
"arguments": [],
|
||||
"typeArguments": null
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"interpreter": null
|
||||
}
|
@ -0,0 +1 @@
|
||||
for await (using of of);
|
@ -0,0 +1,49 @@
|
||||
{
|
||||
"type": "Script",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 25,
|
||||
"ctxt": 0
|
||||
},
|
||||
"body": [
|
||||
{
|
||||
"type": "ForOfStatement",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 25,
|
||||
"ctxt": 0
|
||||
},
|
||||
"await": true,
|
||||
"left": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 12,
|
||||
"end": 17,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "using",
|
||||
"optional": false,
|
||||
"typeAnnotation": null
|
||||
},
|
||||
"right": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 21,
|
||||
"end": 23,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "of",
|
||||
"optional": false
|
||||
},
|
||||
"body": {
|
||||
"type": "EmptyStatement",
|
||||
"span": {
|
||||
"start": 24,
|
||||
"end": 25,
|
||||
"ctxt": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"interpreter": null
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
for (using in []);
|
||||
for (using.foo in []);
|
||||
for (using().foo in []);
|
||||
for (using``.foo in []);
|
@ -0,0 +1,247 @@
|
||||
{
|
||||
"type": "Script",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 92,
|
||||
"ctxt": 0
|
||||
},
|
||||
"body": [
|
||||
{
|
||||
"type": "ForInStatement",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 19,
|
||||
"ctxt": 0
|
||||
},
|
||||
"left": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 6,
|
||||
"end": 11,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "using",
|
||||
"optional": false,
|
||||
"typeAnnotation": null
|
||||
},
|
||||
"right": {
|
||||
"type": "ArrayExpression",
|
||||
"span": {
|
||||
"start": 15,
|
||||
"end": 17,
|
||||
"ctxt": 0
|
||||
},
|
||||
"elements": []
|
||||
},
|
||||
"body": {
|
||||
"type": "EmptyStatement",
|
||||
"span": {
|
||||
"start": 18,
|
||||
"end": 19,
|
||||
"ctxt": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "ForInStatement",
|
||||
"span": {
|
||||
"start": 20,
|
||||
"end": 42,
|
||||
"ctxt": 0
|
||||
},
|
||||
"left": {
|
||||
"type": "MemberExpression",
|
||||
"span": {
|
||||
"start": 25,
|
||||
"end": 34,
|
||||
"ctxt": 0
|
||||
},
|
||||
"object": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 25,
|
||||
"end": 30,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "using",
|
||||
"optional": false
|
||||
},
|
||||
"property": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 31,
|
||||
"end": 34,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "foo",
|
||||
"optional": false
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
"type": "ArrayExpression",
|
||||
"span": {
|
||||
"start": 38,
|
||||
"end": 40,
|
||||
"ctxt": 0
|
||||
},
|
||||
"elements": []
|
||||
},
|
||||
"body": {
|
||||
"type": "EmptyStatement",
|
||||
"span": {
|
||||
"start": 41,
|
||||
"end": 42,
|
||||
"ctxt": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "ForInStatement",
|
||||
"span": {
|
||||
"start": 43,
|
||||
"end": 67,
|
||||
"ctxt": 0
|
||||
},
|
||||
"left": {
|
||||
"type": "MemberExpression",
|
||||
"span": {
|
||||
"start": 48,
|
||||
"end": 59,
|
||||
"ctxt": 0
|
||||
},
|
||||
"object": {
|
||||
"type": "CallExpression",
|
||||
"span": {
|
||||
"start": 48,
|
||||
"end": 55,
|
||||
"ctxt": 0
|
||||
},
|
||||
"callee": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 48,
|
||||
"end": 53,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "using",
|
||||
"optional": false
|
||||
},
|
||||
"arguments": [],
|
||||
"typeArguments": null
|
||||
},
|
||||
"property": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 56,
|
||||
"end": 59,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "foo",
|
||||
"optional": false
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
"type": "ArrayExpression",
|
||||
"span": {
|
||||
"start": 63,
|
||||
"end": 65,
|
||||
"ctxt": 0
|
||||
},
|
||||
"elements": []
|
||||
},
|
||||
"body": {
|
||||
"type": "EmptyStatement",
|
||||
"span": {
|
||||
"start": 66,
|
||||
"end": 67,
|
||||
"ctxt": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "ForInStatement",
|
||||
"span": {
|
||||
"start": 68,
|
||||
"end": 92,
|
||||
"ctxt": 0
|
||||
},
|
||||
"left": {
|
||||
"type": "MemberExpression",
|
||||
"span": {
|
||||
"start": 73,
|
||||
"end": 84,
|
||||
"ctxt": 0
|
||||
},
|
||||
"object": {
|
||||
"type": "TaggedTemplateExpression",
|
||||
"span": {
|
||||
"start": 73,
|
||||
"end": 80,
|
||||
"ctxt": 0
|
||||
},
|
||||
"tag": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 73,
|
||||
"end": 78,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "using",
|
||||
"optional": false
|
||||
},
|
||||
"typeParameters": null,
|
||||
"template": {
|
||||
"type": "TemplateLiteral",
|
||||
"span": {
|
||||
"start": 78,
|
||||
"end": 80,
|
||||
"ctxt": 0
|
||||
},
|
||||
"expressions": [],
|
||||
"quasis": [
|
||||
{
|
||||
"type": "TemplateElement",
|
||||
"span": {
|
||||
"start": 79,
|
||||
"end": 79,
|
||||
"ctxt": 0
|
||||
},
|
||||
"tail": true,
|
||||
"cooked": "",
|
||||
"raw": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"property": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 81,
|
||||
"end": 84,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "foo",
|
||||
"optional": false
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
"type": "ArrayExpression",
|
||||
"span": {
|
||||
"start": 88,
|
||||
"end": 90,
|
||||
"ctxt": 0
|
||||
},
|
||||
"elements": []
|
||||
},
|
||||
"body": {
|
||||
"type": "EmptyStatement",
|
||||
"span": {
|
||||
"start": 91,
|
||||
"end": 92,
|
||||
"ctxt": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"interpreter": null
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
for (
|
||||
using;
|
||||
reader = getReader(););
|
@ -0,0 +1,78 @@
|
||||
{
|
||||
"type": "Script",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 41,
|
||||
"ctxt": 0
|
||||
},
|
||||
"body": [
|
||||
{
|
||||
"type": "ForStatement",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 41,
|
||||
"ctxt": 0
|
||||
},
|
||||
"init": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 9,
|
||||
"end": 14,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "using",
|
||||
"optional": false
|
||||
},
|
||||
"test": {
|
||||
"type": "AssignmentExpression",
|
||||
"span": {
|
||||
"start": 18,
|
||||
"end": 38,
|
||||
"ctxt": 0
|
||||
},
|
||||
"operator": "=",
|
||||
"left": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 18,
|
||||
"end": 24,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "reader",
|
||||
"optional": false,
|
||||
"typeAnnotation": null
|
||||
},
|
||||
"right": {
|
||||
"type": "CallExpression",
|
||||
"span": {
|
||||
"start": 27,
|
||||
"end": 38,
|
||||
"ctxt": 0
|
||||
},
|
||||
"callee": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 27,
|
||||
"end": 36,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "getReader",
|
||||
"optional": false
|
||||
},
|
||||
"arguments": [],
|
||||
"typeArguments": null
|
||||
}
|
||||
},
|
||||
"update": null,
|
||||
"body": {
|
||||
"type": "EmptyStatement",
|
||||
"span": {
|
||||
"start": 40,
|
||||
"end": 41,
|
||||
"ctxt": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"interpreter": null
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
for (using of of);
|
||||
for (using.foo of of);
|
||||
for (using().foo of of);
|
||||
for (using``.foo of of);
|
@ -0,0 +1,255 @@
|
||||
{
|
||||
"type": "Script",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 92,
|
||||
"ctxt": 0
|
||||
},
|
||||
"body": [
|
||||
{
|
||||
"type": "ForOfStatement",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 19,
|
||||
"ctxt": 0
|
||||
},
|
||||
"await": false,
|
||||
"left": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 6,
|
||||
"end": 11,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "using",
|
||||
"optional": false,
|
||||
"typeAnnotation": null
|
||||
},
|
||||
"right": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 15,
|
||||
"end": 17,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "of",
|
||||
"optional": false
|
||||
},
|
||||
"body": {
|
||||
"type": "EmptyStatement",
|
||||
"span": {
|
||||
"start": 18,
|
||||
"end": 19,
|
||||
"ctxt": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "ForOfStatement",
|
||||
"span": {
|
||||
"start": 20,
|
||||
"end": 42,
|
||||
"ctxt": 0
|
||||
},
|
||||
"await": false,
|
||||
"left": {
|
||||
"type": "MemberExpression",
|
||||
"span": {
|
||||
"start": 25,
|
||||
"end": 34,
|
||||
"ctxt": 0
|
||||
},
|
||||
"object": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 25,
|
||||
"end": 30,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "using",
|
||||
"optional": false
|
||||
},
|
||||
"property": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 31,
|
||||
"end": 34,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "foo",
|
||||
"optional": false
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 38,
|
||||
"end": 40,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "of",
|
||||
"optional": false
|
||||
},
|
||||
"body": {
|
||||
"type": "EmptyStatement",
|
||||
"span": {
|
||||
"start": 41,
|
||||
"end": 42,
|
||||
"ctxt": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "ForOfStatement",
|
||||
"span": {
|
||||
"start": 43,
|
||||
"end": 67,
|
||||
"ctxt": 0
|
||||
},
|
||||
"await": false,
|
||||
"left": {
|
||||
"type": "MemberExpression",
|
||||
"span": {
|
||||
"start": 48,
|
||||
"end": 59,
|
||||
"ctxt": 0
|
||||
},
|
||||
"object": {
|
||||
"type": "CallExpression",
|
||||
"span": {
|
||||
"start": 48,
|
||||
"end": 55,
|
||||
"ctxt": 0
|
||||
},
|
||||
"callee": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 48,
|
||||
"end": 53,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "using",
|
||||
"optional": false
|
||||
},
|
||||
"arguments": [],
|
||||
"typeArguments": null
|
||||
},
|
||||
"property": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 56,
|
||||
"end": 59,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "foo",
|
||||
"optional": false
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 63,
|
||||
"end": 65,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "of",
|
||||
"optional": false
|
||||
},
|
||||
"body": {
|
||||
"type": "EmptyStatement",
|
||||
"span": {
|
||||
"start": 66,
|
||||
"end": 67,
|
||||
"ctxt": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "ForOfStatement",
|
||||
"span": {
|
||||
"start": 68,
|
||||
"end": 92,
|
||||
"ctxt": 0
|
||||
},
|
||||
"await": false,
|
||||
"left": {
|
||||
"type": "MemberExpression",
|
||||
"span": {
|
||||
"start": 73,
|
||||
"end": 84,
|
||||
"ctxt": 0
|
||||
},
|
||||
"object": {
|
||||
"type": "TaggedTemplateExpression",
|
||||
"span": {
|
||||
"start": 73,
|
||||
"end": 80,
|
||||
"ctxt": 0
|
||||
},
|
||||
"tag": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 73,
|
||||
"end": 78,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "using",
|
||||
"optional": false
|
||||
},
|
||||
"typeParameters": null,
|
||||
"template": {
|
||||
"type": "TemplateLiteral",
|
||||
"span": {
|
||||
"start": 78,
|
||||
"end": 80,
|
||||
"ctxt": 0
|
||||
},
|
||||
"expressions": [],
|
||||
"quasis": [
|
||||
{
|
||||
"type": "TemplateElement",
|
||||
"span": {
|
||||
"start": 79,
|
||||
"end": 79,
|
||||
"ctxt": 0
|
||||
},
|
||||
"tail": true,
|
||||
"cooked": "",
|
||||
"raw": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"property": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 81,
|
||||
"end": 84,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "foo",
|
||||
"optional": false
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 88,
|
||||
"end": 90,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "of",
|
||||
"optional": false
|
||||
},
|
||||
"body": {
|
||||
"type": "EmptyStatement",
|
||||
"span": {
|
||||
"start": 91,
|
||||
"end": 92,
|
||||
"ctxt": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"interpreter": null
|
||||
}
|
@ -0,0 +1 @@
|
||||
using in using instanceof using;
|
@ -0,0 +1,67 @@
|
||||
{
|
||||
"type": "Script",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 33,
|
||||
"ctxt": 0
|
||||
},
|
||||
"body": [
|
||||
{
|
||||
"type": "ExpressionStatement",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 33,
|
||||
"ctxt": 0
|
||||
},
|
||||
"expression": {
|
||||
"type": "BinaryExpression",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 32,
|
||||
"ctxt": 0
|
||||
},
|
||||
"operator": "instanceof",
|
||||
"left": {
|
||||
"type": "BinaryExpression",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 15,
|
||||
"ctxt": 0
|
||||
},
|
||||
"operator": "in",
|
||||
"left": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 6,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "using",
|
||||
"optional": false
|
||||
},
|
||||
"right": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 10,
|
||||
"end": 15,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "using",
|
||||
"optional": false
|
||||
}
|
||||
},
|
||||
"right": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 27,
|
||||
"end": 32,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "using",
|
||||
"optional": false
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"interpreter": null
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
{
|
||||
using basic = getReader();
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
{
|
||||
"type": "Script",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 33,
|
||||
"ctxt": 0
|
||||
},
|
||||
"body": [
|
||||
{
|
||||
"type": "BlockStatement",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 33,
|
||||
"ctxt": 0
|
||||
},
|
||||
"stmts": [
|
||||
{
|
||||
"type": "UsingDeclaration",
|
||||
"span": {
|
||||
"start": 5,
|
||||
"end": 30,
|
||||
"ctxt": 0
|
||||
},
|
||||
"decls": [
|
||||
{
|
||||
"type": "VariableDeclarator",
|
||||
"span": {
|
||||
"start": 11,
|
||||
"end": 30,
|
||||
"ctxt": 0
|
||||
},
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 11,
|
||||
"end": 16,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "basic",
|
||||
"optional": false,
|
||||
"typeAnnotation": null
|
||||
},
|
||||
"init": {
|
||||
"type": "CallExpression",
|
||||
"span": {
|
||||
"start": 19,
|
||||
"end": 30,
|
||||
"ctxt": 0
|
||||
},
|
||||
"callee": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 19,
|
||||
"end": 28,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "getReader",
|
||||
"optional": false
|
||||
},
|
||||
"arguments": [],
|
||||
"typeArguments": null
|
||||
},
|
||||
"definite": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "EmptyStatement",
|
||||
"span": {
|
||||
"start": 30,
|
||||
"end": 31,
|
||||
"ctxt": 0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"interpreter": null
|
||||
}
|
@ -0,0 +1 @@
|
||||
{ using \u0061b = c; }
|
@ -0,0 +1,69 @@
|
||||
{
|
||||
"type": "Script",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 23,
|
||||
"ctxt": 0
|
||||
},
|
||||
"body": [
|
||||
{
|
||||
"type": "BlockStatement",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 23,
|
||||
"ctxt": 0
|
||||
},
|
||||
"stmts": [
|
||||
{
|
||||
"type": "UsingDeclaration",
|
||||
"span": {
|
||||
"start": 3,
|
||||
"end": 20,
|
||||
"ctxt": 0
|
||||
},
|
||||
"decls": [
|
||||
{
|
||||
"type": "VariableDeclarator",
|
||||
"span": {
|
||||
"start": 9,
|
||||
"end": 20,
|
||||
"ctxt": 0
|
||||
},
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 9,
|
||||
"end": 16,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "ab",
|
||||
"optional": false,
|
||||
"typeAnnotation": null
|
||||
},
|
||||
"init": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 19,
|
||||
"end": 20,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "c",
|
||||
"optional": false
|
||||
},
|
||||
"definite": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "EmptyStatement",
|
||||
"span": {
|
||||
"start": 20,
|
||||
"end": 21,
|
||||
"ctxt": 0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"interpreter": null
|
||||
}
|
@ -0,0 +1 @@
|
||||
{ using 𠮷 = foo(); }
|
@ -0,0 +1,79 @@
|
||||
{
|
||||
"type": "Script",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 24,
|
||||
"ctxt": 0
|
||||
},
|
||||
"body": [
|
||||
{
|
||||
"type": "BlockStatement",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 24,
|
||||
"ctxt": 0
|
||||
},
|
||||
"stmts": [
|
||||
{
|
||||
"type": "UsingDeclaration",
|
||||
"span": {
|
||||
"start": 3,
|
||||
"end": 21,
|
||||
"ctxt": 0
|
||||
},
|
||||
"decls": [
|
||||
{
|
||||
"type": "VariableDeclarator",
|
||||
"span": {
|
||||
"start": 9,
|
||||
"end": 21,
|
||||
"ctxt": 0
|
||||
},
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 9,
|
||||
"end": 13,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "𠮷",
|
||||
"optional": false,
|
||||
"typeAnnotation": null
|
||||
},
|
||||
"init": {
|
||||
"type": "CallExpression",
|
||||
"span": {
|
||||
"start": 16,
|
||||
"end": 21,
|
||||
"ctxt": 0
|
||||
},
|
||||
"callee": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 16,
|
||||
"end": 19,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "foo",
|
||||
"optional": false
|
||||
},
|
||||
"arguments": [],
|
||||
"typeArguments": null
|
||||
},
|
||||
"definite": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "EmptyStatement",
|
||||
"span": {
|
||||
"start": 21,
|
||||
"end": 22,
|
||||
"ctxt": 0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"interpreter": null
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
{
|
||||
using using = of;
|
||||
for (using using of of);
|
||||
}
|
@ -0,0 +1,127 @@
|
||||
{
|
||||
"type": "Script",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 51,
|
||||
"ctxt": 0
|
||||
},
|
||||
"body": [
|
||||
{
|
||||
"type": "BlockStatement",
|
||||
"span": {
|
||||
"start": 1,
|
||||
"end": 51,
|
||||
"ctxt": 0
|
||||
},
|
||||
"stmts": [
|
||||
{
|
||||
"type": "UsingDeclaration",
|
||||
"span": {
|
||||
"start": 5,
|
||||
"end": 21,
|
||||
"ctxt": 0
|
||||
},
|
||||
"decls": [
|
||||
{
|
||||
"type": "VariableDeclarator",
|
||||
"span": {
|
||||
"start": 11,
|
||||
"end": 21,
|
||||
"ctxt": 0
|
||||
},
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 11,
|
||||
"end": 16,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "using",
|
||||
"optional": false,
|
||||
"typeAnnotation": null
|
||||
},
|
||||
"init": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 19,
|
||||
"end": 21,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "of",
|
||||
"optional": false
|
||||
},
|
||||
"definite": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "EmptyStatement",
|
||||
"span": {
|
||||
"start": 21,
|
||||
"end": 22,
|
||||
"ctxt": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "ForOfStatement",
|
||||
"span": {
|
||||
"start": 25,
|
||||
"end": 49,
|
||||
"ctxt": 0
|
||||
},
|
||||
"await": false,
|
||||
"left": {
|
||||
"type": "UsingDeclaration",
|
||||
"span": {
|
||||
"start": 30,
|
||||
"end": 41,
|
||||
"ctxt": 0
|
||||
},
|
||||
"decls": [
|
||||
{
|
||||
"type": "VariableDeclarator",
|
||||
"span": {
|
||||
"start": 30,
|
||||
"end": 41,
|
||||
"ctxt": 0
|
||||
},
|
||||
"id": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 36,
|
||||
"end": 41,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "using",
|
||||
"optional": false,
|
||||
"typeAnnotation": null
|
||||
},
|
||||
"init": null,
|
||||
"definite": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"right": {
|
||||
"type": "Identifier",
|
||||
"span": {
|
||||
"start": 45,
|
||||
"end": 47,
|
||||
"ctxt": 0
|
||||
},
|
||||
"value": "of",
|
||||
"optional": false
|
||||
},
|
||||
"body": {
|
||||
"type": "EmptyStatement",
|
||||
"span": {
|
||||
"start": 48,
|
||||
"end": 49,
|
||||
"ctxt": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"interpreter": null
|
||||
}
|
@ -1056,8 +1056,8 @@ impl Visit for Shower<'_> {
|
||||
n.visit_children_with(self)
|
||||
}
|
||||
|
||||
fn visit_var_decl_or_pat(&mut self, n: &VarDeclOrPat) {
|
||||
self.show("VarDeclOrPat", n);
|
||||
fn visit_for_head(&mut self, n: &ForHead) {
|
||||
self.show("ForHead", n);
|
||||
n.visit_children_with(self)
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@
|
||||
6 | `-> }
|
||||
`----
|
||||
|
||||
x VarDeclOrPat
|
||||
x ForHead
|
||||
,-[$DIR/tests/span/js/stmt/for-in.js:1:1]
|
||||
1 | for (const a in [1, 2, 3]) {
|
||||
: ^^^^^^^
|
||||
|
@ -27,7 +27,7 @@
|
||||
3 | `-> }
|
||||
`----
|
||||
|
||||
x VarDeclOrPat
|
||||
x ForHead
|
||||
,-[$DIR/tests/span/js/stmt/for-of.js:1:1]
|
||||
1 | for await (const a of foo) {
|
||||
: ^^^^^^^
|
||||
|
@ -2,10 +2,20 @@ use swc_ecma_ast::*;
|
||||
|
||||
impl_enum!(
|
||||
Decl,
|
||||
[Class, Fn, Var, TsInterface, TsTypeAlias, TsEnum, TsModule]
|
||||
[
|
||||
Class,
|
||||
Fn,
|
||||
Var,
|
||||
TsInterface,
|
||||
TsTypeAlias,
|
||||
TsEnum,
|
||||
TsModule,
|
||||
Using
|
||||
]
|
||||
);
|
||||
|
||||
impl_struct!(ClassDecl, [ident, class]);
|
||||
impl_struct!(FnDecl, [ident, function]);
|
||||
impl_struct!(VarDecl, [span, kind, declare, decls]);
|
||||
impl_struct!(VarDeclarator, [span, name, init, definite]);
|
||||
impl_struct!(UsingDecl, [span, decls]);
|
||||
|
@ -28,7 +28,7 @@ impl_struct!(ReturnStmt, [span, arg]);
|
||||
impl_struct!(ExprStmt, [span, expr]);
|
||||
|
||||
impl_enum!(VarDeclOrExpr, [VarDecl, Expr]);
|
||||
impl_enum!(VarDeclOrPat, [VarDecl, Pat]);
|
||||
impl_enum!(ForHead, [VarDecl, UsingDecl, Pat]);
|
||||
|
||||
impl_struct!(SwitchCase, [span, test, cons]);
|
||||
|
||||
|
@ -496,7 +496,7 @@ impl VisitMut for Fixer<'_> {
|
||||
|
||||
if !s.is_await {
|
||||
match &s.left {
|
||||
VarDeclOrPat::Pat(p)
|
||||
ForHead::Pat(p)
|
||||
if matches!(
|
||||
&**p,
|
||||
Pat::Ident(BindingIdent {
|
||||
@ -509,12 +509,12 @@ impl VisitMut for Fixer<'_> {
|
||||
) =>
|
||||
{
|
||||
let expr = Expr::Ident(p.clone().expect_ident().id);
|
||||
s.left = VarDeclOrPat::Pat(Pat::Expr(Box::new(expr)).into());
|
||||
s.left = ForHead::Pat(Pat::Expr(Box::new(expr)).into());
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
if let VarDeclOrPat::Pat(e) = &mut s.left {
|
||||
if let ForHead::Pat(e) = &mut s.left {
|
||||
if let Pat::Expr(expr) = &mut **e {
|
||||
if let Expr::Ident(Ident {
|
||||
sym: js_word!("async"),
|
||||
|
@ -1855,9 +1855,9 @@ impl VisitMut for Hoister<'_, '_> {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_mut_var_decl_or_pat(&mut self, n: &mut VarDeclOrPat) {
|
||||
fn visit_mut_for_head(&mut self, n: &mut ForHead) {
|
||||
match n {
|
||||
VarDeclOrPat::VarDecl(v)
|
||||
ForHead::VarDecl(v)
|
||||
if matches!(
|
||||
&**v,
|
||||
VarDecl {
|
||||
@ -1874,7 +1874,7 @@ impl VisitMut for Hoister<'_, '_> {
|
||||
// console.log(a);
|
||||
// }
|
||||
// }
|
||||
VarDeclOrPat::Pat(..) => {}
|
||||
ForHead::Pat(..) => {}
|
||||
_ => {
|
||||
n.visit_mut_children_with(self);
|
||||
}
|
||||
|
@ -438,7 +438,7 @@ impl VisitMut for BlockScoping {
|
||||
|
||||
fn visit_mut_for_in_stmt(&mut self, node: &mut ForInStmt) {
|
||||
let blockifyed = self.blockify_for_stmt_body(&mut node.body);
|
||||
let lexical_var = if let VarDeclOrPat::VarDecl(decl) = &node.left {
|
||||
let lexical_var = if let ForHead::VarDecl(decl) = &node.left {
|
||||
find_lexical_vars(decl)
|
||||
} else {
|
||||
Vec::new()
|
||||
@ -463,7 +463,7 @@ impl VisitMut for BlockScoping {
|
||||
|
||||
fn visit_mut_for_of_stmt(&mut self, node: &mut ForOfStmt) {
|
||||
let blockifyed = self.blockify_for_stmt_body(&mut node.body);
|
||||
let vars = if let VarDeclOrPat::VarDecl(decl) = &node.left {
|
||||
let vars = if let ForHead::VarDecl(decl) = &node.left {
|
||||
find_lexical_vars(decl)
|
||||
} else {
|
||||
Vec::new()
|
||||
|
@ -311,7 +311,7 @@ impl VisitMut for BlockScopedVars {
|
||||
n.right.visit_mut_with(self);
|
||||
|
||||
match &n.left {
|
||||
VarDeclOrPat::VarDecl(v)
|
||||
ForHead::VarDecl(v)
|
||||
if matches!(
|
||||
&**v,
|
||||
VarDecl {
|
||||
@ -336,7 +336,7 @@ impl VisitMut for BlockScopedVars {
|
||||
n.right.visit_mut_with(self);
|
||||
|
||||
match &n.left {
|
||||
VarDeclOrPat::VarDecl(v)
|
||||
ForHead::VarDecl(v)
|
||||
if matches!(
|
||||
&**v,
|
||||
VarDecl {
|
||||
|
@ -54,7 +54,7 @@ macro_rules! impl_for_for_stmt {
|
||||
($name:ident, $T:tt) => {
|
||||
fn $name(&mut self, for_stmt: &mut $T) {
|
||||
let (left, stmt) = match &mut for_stmt.left {
|
||||
VarDeclOrPat::VarDecl(var_decl) => {
|
||||
ForHead::VarDecl(var_decl) => {
|
||||
let has_complex = var_decl.decls.iter().any(|d| match d.name {
|
||||
Pat::Ident(_) => false,
|
||||
_ => true,
|
||||
@ -99,13 +99,13 @@ macro_rules! impl_for_for_stmt {
|
||||
.into();
|
||||
(left, stmt)
|
||||
}
|
||||
VarDeclOrPat::Pat(pat) => match **pat {
|
||||
ForHead::Pat(pat) => match **pat {
|
||||
Pat::Ident(..) => {
|
||||
return;
|
||||
}
|
||||
_ => {
|
||||
let left_ident = make_ref_ident_for_for_stmt();
|
||||
let left = VarDeclOrPat::Pat(left_ident.clone().into());
|
||||
let left = ForHead::Pat(left_ident.clone().into());
|
||||
// Unpack variables
|
||||
let stmt = AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
@ -117,6 +117,10 @@ macro_rules! impl_for_for_stmt {
|
||||
(left, stmt)
|
||||
}
|
||||
},
|
||||
|
||||
ForHead::UsingDecl(..) => {
|
||||
unreachable!("using declaration must be removed by previous pass")
|
||||
}
|
||||
};
|
||||
|
||||
for_stmt.left = left;
|
||||
|
@ -140,7 +140,7 @@ impl ForOf {
|
||||
};
|
||||
|
||||
match left {
|
||||
VarDeclOrPat::VarDecl(var) => {
|
||||
ForHead::VarDecl(var) => {
|
||||
assert_eq!(
|
||||
var.decls.len(),
|
||||
1,
|
||||
@ -163,7 +163,7 @@ impl ForOf {
|
||||
)
|
||||
}
|
||||
|
||||
VarDeclOrPat::Pat(pat) => prepend_stmt(
|
||||
ForHead::Pat(pat) => prepend_stmt(
|
||||
&mut body.stmts,
|
||||
AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
@ -173,6 +173,10 @@ impl ForOf {
|
||||
}
|
||||
.into_stmt(),
|
||||
),
|
||||
|
||||
ForHead::UsingDecl(..) => {
|
||||
unreachable!("using declaration must be removed by previous pass")
|
||||
}
|
||||
}
|
||||
|
||||
let stmt = Stmt::For(ForStmt {
|
||||
@ -236,7 +240,7 @@ impl ForOf {
|
||||
};
|
||||
|
||||
match left {
|
||||
VarDeclOrPat::VarDecl(var) => {
|
||||
ForHead::VarDecl(var) => {
|
||||
assert_eq!(
|
||||
var.decls.len(),
|
||||
1,
|
||||
@ -259,7 +263,7 @@ impl ForOf {
|
||||
)
|
||||
}
|
||||
|
||||
VarDeclOrPat::Pat(pat) => prepend_stmt(
|
||||
ForHead::Pat(pat) => prepend_stmt(
|
||||
&mut body.stmts,
|
||||
AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
@ -269,6 +273,10 @@ impl ForOf {
|
||||
}
|
||||
.into_stmt(),
|
||||
),
|
||||
|
||||
ForHead::UsingDecl(..) => {
|
||||
unreachable!("using declaration must be removed by previous pass")
|
||||
}
|
||||
}
|
||||
|
||||
// !(_step = _iterator()).done;
|
||||
@ -332,7 +340,7 @@ impl ForOf {
|
||||
body.stmts.insert(
|
||||
0,
|
||||
match left {
|
||||
VarDeclOrPat::VarDecl(mut var) => {
|
||||
ForHead::VarDecl(mut var) => {
|
||||
assert_eq!(var.decls.len(), 1);
|
||||
VarDecl {
|
||||
span: var.span,
|
||||
@ -345,13 +353,17 @@ impl ForOf {
|
||||
}
|
||||
.into()
|
||||
}
|
||||
VarDeclOrPat::Pat(pat) => AssignExpr {
|
||||
ForHead::Pat(pat) => AssignExpr {
|
||||
span: DUMMY_SP,
|
||||
left: PatOrExpr::Pat(pat),
|
||||
op: op!("="),
|
||||
right: step_value,
|
||||
}
|
||||
.into_stmt(),
|
||||
|
||||
ForHead::UsingDecl(..) => {
|
||||
unreachable!("using declaration must be removed by previous pass")
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
|
@ -949,7 +949,7 @@ impl VisitMut for Generator {
|
||||
self.begin_script_loop_block();
|
||||
}
|
||||
|
||||
if let VarDeclOrPat::VarDecl(initializer) = &mut node.left {
|
||||
if let ForHead::VarDecl(initializer) = &mut node.left {
|
||||
for variable in &initializer.decls {
|
||||
self.hoist_variable_declaration(variable.name.as_ident().unwrap());
|
||||
}
|
||||
@ -1755,7 +1755,7 @@ impl Generator {
|
||||
node.right.visit_mut_with(self);
|
||||
self.emit_stmt(Stmt::ForIn(ForInStmt {
|
||||
span: DUMMY_SP,
|
||||
left: VarDeclOrPat::Pat(key.clone().into()),
|
||||
left: ForHead::Pat(key.clone().into()),
|
||||
right: node.right.take(),
|
||||
body: Box::new(Stmt::Expr(ExprStmt {
|
||||
span: DUMMY_SP,
|
||||
@ -1788,17 +1788,21 @@ impl Generator {
|
||||
);
|
||||
|
||||
let variable = match node.left {
|
||||
VarDeclOrPat::VarDecl(initializer) => {
|
||||
ForHead::VarDecl(initializer) => {
|
||||
for variable in initializer.decls.iter() {
|
||||
self.hoist_variable_declaration(variable.name.as_ident().unwrap());
|
||||
}
|
||||
|
||||
initializer.decls[0].name.clone()
|
||||
}
|
||||
VarDeclOrPat::Pat(mut initializer) => {
|
||||
ForHead::Pat(mut initializer) => {
|
||||
initializer.visit_mut_with(self);
|
||||
*initializer
|
||||
}
|
||||
|
||||
ForHead::UsingDecl(..) => {
|
||||
unreachable!("using declaration must be removed by previous pass")
|
||||
}
|
||||
};
|
||||
self.emit_assignment(
|
||||
PatOrExpr::Pat(Box::new(variable)),
|
||||
|
@ -592,7 +592,7 @@ fn handle_await_for(stmt: &mut Stmt, is_async_generator: bool) {
|
||||
}
|
||||
|
||||
match s.left {
|
||||
VarDeclOrPat::VarDecl(v) => {
|
||||
ForHead::VarDecl(v) => {
|
||||
let var = v.decls.into_iter().next().unwrap();
|
||||
let var_decl = VarDeclarator {
|
||||
span: DUMMY_SP,
|
||||
@ -610,7 +610,7 @@ fn handle_await_for(stmt: &mut Stmt, is_async_generator: bool) {
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
VarDeclOrPat::Pat(p) => {
|
||||
ForHead::Pat(p) => {
|
||||
for_loop_body.push(Stmt::Expr(ExprStmt {
|
||||
span: DUMMY_SP,
|
||||
expr: Box::new(Expr::Assign(AssignExpr {
|
||||
@ -621,6 +621,10 @@ fn handle_await_for(stmt: &mut Stmt, is_async_generator: bool) {
|
||||
})),
|
||||
}));
|
||||
}
|
||||
|
||||
ForHead::UsingDecl(..) => {
|
||||
unreachable!("using declaration must be removed by previous pass")
|
||||
}
|
||||
}
|
||||
|
||||
for_loop_body.extend(orig_body);
|
||||
|
@ -66,7 +66,7 @@ macro_rules! impl_for_for_stmt {
|
||||
let mut stmt = None;
|
||||
|
||||
let left = match &mut for_stmt.left {
|
||||
VarDeclOrPat::VarDecl(var_decl) => {
|
||||
ForHead::VarDecl(var_decl) => {
|
||||
let ref_ident = private_ident!("_ref");
|
||||
|
||||
// Unpack variables
|
||||
@ -105,7 +105,7 @@ macro_rules! impl_for_for_stmt {
|
||||
}
|
||||
.into()
|
||||
}
|
||||
VarDeclOrPat::Pat(pat) => {
|
||||
ForHead::Pat(pat) => {
|
||||
let var_ident = private_ident!("_ref");
|
||||
let index = self.vars.len();
|
||||
let pat = pat.take();
|
||||
@ -160,6 +160,10 @@ macro_rules! impl_for_for_stmt {
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
ForHead::UsingDecl(..) => {
|
||||
unreachable!("using declaration must be removed by previous pass")
|
||||
}
|
||||
};
|
||||
for_stmt.left = left;
|
||||
|
||||
|
@ -446,8 +446,8 @@ impl SystemJs {
|
||||
}
|
||||
}
|
||||
|
||||
fn hoist_for_var_decl(&mut self, var_decl_or_pat: VarDeclOrPat) -> VarDeclOrPat {
|
||||
if let VarDeclOrPat::VarDecl(mut var_decl) = var_decl_or_pat {
|
||||
fn hoist_for_var_decl(&mut self, var_decl_or_pat: ForHead) -> ForHead {
|
||||
if let ForHead::VarDecl(mut var_decl) = var_decl_or_pat {
|
||||
if var_decl.kind == VarDeclKind::Var {
|
||||
let var_declarator = var_decl.decls.remove(0);
|
||||
let mut tos: Vec<Id> = vec![];
|
||||
@ -469,9 +469,9 @@ impl SystemJs {
|
||||
.push(Ident::new(to.0, DUMMY_SP.with_ctxt(to.1)));
|
||||
}
|
||||
|
||||
VarDeclOrPat::Pat(var_declarator.name.into())
|
||||
ForHead::Pat(var_declarator.name.into())
|
||||
} else {
|
||||
VarDeclOrPat::VarDecl(var_decl)
|
||||
ForHead::VarDecl(var_decl)
|
||||
}
|
||||
} else {
|
||||
var_decl_or_pat
|
||||
|
@ -1007,10 +1007,10 @@ impl VisitMut for TreeShaker {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_mut_var_decl_or_pat(&mut self, n: &mut VarDeclOrPat) {
|
||||
fn visit_mut_for_head(&mut self, n: &mut ForHead) {
|
||||
match n {
|
||||
VarDeclOrPat::VarDecl(..) => {}
|
||||
VarDeclOrPat::Pat(v) => {
|
||||
ForHead::VarDecl(..) | ForHead::UsingDecl(..) => {}
|
||||
ForHead::Pat(v) => {
|
||||
v.visit_mut_with(self);
|
||||
}
|
||||
}
|
||||
|
@ -1616,7 +1616,7 @@ impl VisitMut for SimplifyExpr {
|
||||
self.is_modifying = old;
|
||||
}
|
||||
|
||||
fn visit_mut_var_decl_or_pat(&mut self, n: &mut VarDeclOrPat) {
|
||||
fn visit_mut_for_head(&mut self, n: &mut ForHead) {
|
||||
let old = self.is_modifying;
|
||||
self.is_modifying = true;
|
||||
n.visit_mut_children_with(self);
|
||||
|
@ -400,6 +400,15 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
Decl::Using(ref var) => {
|
||||
let mut names: Vec<Id> = vec![];
|
||||
var.decls.visit_with(&mut VarCollector { to: &mut names });
|
||||
|
||||
for name in names {
|
||||
self.store(name.0.clone(), name.1, true);
|
||||
}
|
||||
}
|
||||
|
||||
Decl::TsEnum(e) => {
|
||||
// Currently swc cannot remove constant enums
|
||||
self.store(e.id.sym.clone(), e.id.span.ctxt, true);
|
||||
@ -1541,6 +1550,9 @@ where
|
||||
self.decl_names.insert(class.ident.to_id());
|
||||
class.class.visit_with(self);
|
||||
}
|
||||
Decl::Using(d) => {
|
||||
d.decls.visit_with(self);
|
||||
}
|
||||
Decl::Fn(f) => {
|
||||
self.decl_names.insert(f.ident.to_id());
|
||||
f.function.visit_with(self)
|
||||
@ -1745,7 +1757,7 @@ fn is_decl_concrete(d: &Decl) -> bool {
|
||||
match d {
|
||||
Decl::TsEnum(..) => true,
|
||||
Decl::TsTypeAlias(..) | Decl::TsInterface(..) => false,
|
||||
Decl::Class(_) | Decl::Fn(_) | Decl::Var(_) => true,
|
||||
Decl::Class(_) | Decl::Fn(_) | Decl::Var(_) | Decl::Using(..) => true,
|
||||
Decl::TsModule(b) => ts_module_has_concrete(b),
|
||||
}
|
||||
}
|
||||
|
@ -635,6 +635,7 @@ define!({
|
||||
Class(ClassDecl),
|
||||
Fn(FnDecl),
|
||||
Var(Box<VarDecl>),
|
||||
Using(Box<UsingDecl>),
|
||||
TsInterface(Box<TsInterfaceDecl>),
|
||||
TsTypeAlias(Box<TsTypeAliasDecl>),
|
||||
TsEnum(Box<TsEnumDecl>),
|
||||
@ -1405,14 +1406,14 @@ define!({
|
||||
}
|
||||
pub struct ForInStmt {
|
||||
pub span: Span,
|
||||
pub left: VarDeclOrPat,
|
||||
pub left: ForHead,
|
||||
pub right: Box<Expr>,
|
||||
pub body: Box<Stmt>,
|
||||
}
|
||||
pub struct ForOfStmt {
|
||||
pub span: Span,
|
||||
pub is_await: bool,
|
||||
pub left: VarDeclOrPat,
|
||||
pub left: ForHead,
|
||||
pub right: Box<Expr>,
|
||||
pub body: Box<Stmt>,
|
||||
}
|
||||
@ -1426,8 +1427,9 @@ define!({
|
||||
pub param: Option<Pat>,
|
||||
pub body: BlockStmt,
|
||||
}
|
||||
pub enum VarDeclOrPat {
|
||||
pub enum ForHead {
|
||||
VarDecl(Box<VarDecl>),
|
||||
UsingDecl(Box<UsingDecl>),
|
||||
Pat(Box<Pat>),
|
||||
}
|
||||
pub enum VarDeclOrExpr {
|
||||
@ -1884,6 +1886,12 @@ define!({
|
||||
Private(PrivateName),
|
||||
Public(PropName),
|
||||
}
|
||||
|
||||
pub struct UsingDecl {
|
||||
pub span: Span,
|
||||
|
||||
pub decls: Vec<VarDeclarator>,
|
||||
}
|
||||
});
|
||||
|
||||
#[macro_export]
|
||||
|
@ -28,6 +28,8 @@ pub enum Declaration {
|
||||
FuncDecl(FunctionDeclaration),
|
||||
#[tag("VariableDeclaration")]
|
||||
VarDecl(VariableDeclaration),
|
||||
#[tag("UsingDeclaration")]
|
||||
UsingDecl(UsingDeclaration),
|
||||
#[tag("ClassDeclaration")]
|
||||
ClassDecl(ClassDeclaration),
|
||||
#[tag("ExportAllDeclaration")]
|
||||
@ -282,3 +284,13 @@ pub struct EnumDeclaration {
|
||||
pub id: Identifier,
|
||||
pub body: EnumBody,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[ast_serde("EnumDeclaration")]
|
||||
pub struct UsingDeclaration {
|
||||
#[serde(flatten)]
|
||||
pub base: BaseNode,
|
||||
|
||||
#[serde(default)]
|
||||
pub declarations: Vec<VariableDeclarator>,
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ use crate::{
|
||||
TSInterfaceDeclaration, TSModuleDeclaration, TSNamespaceExportDeclaration,
|
||||
TSTypeAliasDeclaration,
|
||||
},
|
||||
UsingDeclaration,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
@ -103,6 +104,8 @@ pub enum Statement {
|
||||
TypeAlias(TypeAlias),
|
||||
#[tag("EnumDeclaration")]
|
||||
EnumDecl(EnumDeclaration),
|
||||
#[tag("UsingDeclaration")]
|
||||
UsingDecl(UsingDeclaration),
|
||||
#[tag("TSDeclareFunction")]
|
||||
TSDeclFunc(TSDeclareFunction),
|
||||
#[tag("TSInterfaceDeclaration")]
|
||||
|
@ -1,8 +1,8 @@
|
||||
use copyless::BoxHelper;
|
||||
use swc_ecma_ast::{ClassDecl, Decl, FnDecl, VarDecl, VarDeclKind, VarDeclarator};
|
||||
use swc_ecma_ast::{ClassDecl, Decl, FnDecl, UsingDecl, VarDecl, VarDeclKind, VarDeclarator};
|
||||
use swc_estree_ast::{
|
||||
ClassBody, ClassDeclaration, Declaration, FunctionDeclaration, VariableDeclaration,
|
||||
VariableDeclarationKind, VariableDeclarator,
|
||||
ClassBody, ClassDeclaration, Declaration, FunctionDeclaration, UsingDeclaration,
|
||||
VariableDeclaration, VariableDeclarationKind, VariableDeclarator,
|
||||
};
|
||||
|
||||
use crate::babelify::{extract_class_body_span, Babelify, Context};
|
||||
@ -15,6 +15,7 @@ impl Babelify for Decl {
|
||||
Decl::Class(d) => Declaration::ClassDecl(d.babelify(ctx)),
|
||||
Decl::Fn(d) => Declaration::FuncDecl(d.babelify(ctx)),
|
||||
Decl::Var(d) => Declaration::VarDecl(d.babelify(ctx)),
|
||||
Decl::Using(d) => Declaration::UsingDecl(d.babelify(ctx)),
|
||||
Decl::TsInterface(d) => Declaration::TSInterfaceDecl(d.babelify(ctx)),
|
||||
Decl::TsTypeAlias(d) => Declaration::TSTypeAliasDecl(d.babelify(ctx)),
|
||||
Decl::TsEnum(d) => Declaration::TSEnumDecl(d.babelify(ctx)),
|
||||
@ -123,3 +124,14 @@ impl Babelify for VarDeclarator {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Babelify for UsingDecl {
|
||||
type Output = UsingDeclaration;
|
||||
|
||||
fn babelify(self, ctx: &Context) -> Self::Output {
|
||||
UsingDeclaration {
|
||||
base: ctx.base(self.span),
|
||||
declarations: self.decls.babelify(ctx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
use copyless::BoxHelper;
|
||||
use swc_ecma_ast::{
|
||||
BlockStmt, BreakStmt, CatchClause, ContinueStmt, DebuggerStmt, Decl, DoWhileStmt, EmptyStmt,
|
||||
ExprStmt, ForInStmt, ForOfStmt, ForStmt, IfStmt, LabeledStmt, ReturnStmt, Stmt, SwitchCase,
|
||||
SwitchStmt, ThrowStmt, TryStmt, VarDeclOrExpr, VarDeclOrPat, WhileStmt, WithStmt,
|
||||
ExprStmt, ForHead, ForInStmt, ForOfStmt, ForStmt, IfStmt, LabeledStmt, ReturnStmt, Stmt,
|
||||
SwitchCase, SwitchStmt, ThrowStmt, TryStmt, VarDeclOrExpr, WhileStmt, WithStmt,
|
||||
};
|
||||
use swc_estree_ast::{
|
||||
BlockStatement, BreakStatement, CatchClause as BabelCatchClause, ContinueStatement,
|
||||
@ -56,6 +56,7 @@ impl Babelify for Stmt {
|
||||
Decl::Class(d) => Statement::ClassDecl(d.babelify(ctx)),
|
||||
Decl::Fn(d) => Statement::FuncDecl(d.babelify(ctx)),
|
||||
Decl::Var(d) => Statement::VarDecl(d.babelify(ctx)),
|
||||
Decl::Using(d) => Statement::UsingDecl(d.babelify(ctx)),
|
||||
Decl::TsInterface(d) => Statement::TSInterfaceDecl(d.babelify(ctx)),
|
||||
Decl::TsTypeAlias(d) => Statement::TSTypeAliasDecl(d.babelify(ctx)),
|
||||
Decl::TsEnum(d) => Statement::TSEnumDecl(d.babelify(ctx)),
|
||||
@ -300,13 +301,16 @@ impl Babelify for CatchClause {
|
||||
}
|
||||
}
|
||||
|
||||
impl Babelify for VarDeclOrPat {
|
||||
impl Babelify for ForHead {
|
||||
type Output = ForStmtLeft;
|
||||
|
||||
fn babelify(self, ctx: &Context) -> Self::Output {
|
||||
match self {
|
||||
VarDeclOrPat::VarDecl(v) => ForStmtLeft::VarDecl(v.babelify(ctx)),
|
||||
VarDeclOrPat::Pat(p) => ForStmtLeft::LVal(p.babelify(ctx).into()),
|
||||
ForHead::VarDecl(v) => ForStmtLeft::VarDecl(v.babelify(ctx)),
|
||||
ForHead::Pat(p) => ForStmtLeft::LVal(p.babelify(ctx).into()),
|
||||
_ => {
|
||||
todo!("ForHead::UsingDecl({self:?})")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,12 +2,12 @@ use swc_common::DUMMY_SP;
|
||||
use swc_ecma_ast::{
|
||||
BlockStmt, BreakStmt, ClassDecl, ClassExpr, ContinueStmt, DebuggerStmt, Decl, DefaultDecl,
|
||||
DoWhileStmt, EmptyStmt, ExportAll, ExportDecl, ExportDefaultDecl, ExportDefaultExpr,
|
||||
ExportNamedSpecifier, Expr, ExprStmt, FnDecl, FnExpr, ForInStmt, ForOfStmt, ForStmt, IfStmt,
|
||||
ImportDecl, ImportNamedSpecifier, ImportSpecifier, ImportStarAsSpecifier, KeyValueProp,
|
||||
ExportNamedSpecifier, Expr, ExprStmt, FnDecl, FnExpr, ForHead, ForInStmt, ForOfStmt, ForStmt,
|
||||
IfStmt, ImportDecl, ImportNamedSpecifier, ImportSpecifier, ImportStarAsSpecifier, KeyValueProp,
|
||||
LabeledStmt, Lit, ModuleDecl, ModuleItem, NamedExport, ObjectLit, Pat, Prop, PropName,
|
||||
PropOrSpread, ReturnStmt, Stmt, SwitchStmt, ThrowStmt, TryStmt, TsExportAssignment,
|
||||
TsInterfaceDecl, TsModuleDecl, TsTypeAliasDecl, VarDecl, VarDeclKind, VarDeclOrExpr,
|
||||
VarDeclOrPat, VarDeclarator, WhileStmt, WithStmt,
|
||||
VarDeclarator, WhileStmt, WithStmt,
|
||||
};
|
||||
use swc_estree_ast::{
|
||||
BlockStatement, BreakStatement, ClassDeclaration, ContinueStatement, DebuggerStatement,
|
||||
@ -178,12 +178,12 @@ impl Swcify for ForInStatement {
|
||||
}
|
||||
|
||||
impl Swcify for ForStmtLeft {
|
||||
type Output = VarDeclOrPat;
|
||||
type Output = ForHead;
|
||||
|
||||
fn swcify(self, ctx: &Context) -> Self::Output {
|
||||
match self {
|
||||
ForStmtLeft::VarDecl(v) => VarDeclOrPat::VarDecl(v.swcify(ctx).into()),
|
||||
ForStmtLeft::LVal(v) => VarDeclOrPat::Pat(v.swcify(ctx).into()),
|
||||
ForStmtLeft::VarDecl(v) => ForHead::VarDecl(v.swcify(ctx).into()),
|
||||
ForStmtLeft::LVal(v) => ForHead::Pat(v.swcify(ctx).into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user