Skip to content

Commit

Permalink
feat: dynamic import phase
Browse files Browse the repository at this point in the history
  • Loading branch information
magic-akari committed Nov 13, 2023
1 parent f35c67f commit 998d44d
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 27 deletions.
8 changes: 6 additions & 2 deletions crates/swc_ecma_ast/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use crate::{
TsAsExpr, TsConstAssertion, TsInstantiation, TsNonNullExpr, TsSatisfiesExpr, TsTypeAnn,
TsTypeAssertion, TsTypeParamDecl, TsTypeParamInstantiation,
},
ComputedPropName, Id, Invalid,
ComputedPropName, Id, ImportPhase, Invalid,
};

#[ast_node(no_clone)]
Expand Down Expand Up @@ -1124,11 +1124,15 @@ impl Take for Super {
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
pub struct Import {
pub span: Span,
pub phase: ImportPhase,
}

impl Take for Import {
fn dummy() -> Self {
Import { span: DUMMY_SP }
Import {
span: DUMMY_SP,
phase: ImportPhase::default(),
}
}
}

Expand Down
11 changes: 11 additions & 0 deletions crates/swc_ecma_codegen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,17 @@ where
#[emitter]
fn emit_import_callee(&mut self, node: &Import) -> Result {
keyword!(node.span, "import");
match node.phase {
ImportPhase::Source => {
punct!(".");
keyword!("source")
}
ImportPhase::Defer => {
punct!(".");
keyword!("defer")
}
_ => {}
}
}

#[emitter]
Expand Down
69 changes: 47 additions & 22 deletions crates/swc_ecma_parser/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,19 +259,17 @@ impl<I: Tokens> Parser<I> {

tok!("import") => {
let import = self.parse_ident_name()?;

if is!(self, '.') {
self.state.found_module_item = true;
if !self.ctx().can_be_module {
let span = span!(self, start);
self.emit_err(span, SyntaxError::ImportMetaInScript);
}
return self
.parse_import_meta_prop(Import { span: import.span })
.map(Expr::MetaProp)
.map(Box::new);
return self.parse_import_meta_prop(start, import.span);
}

return self.parse_dynamic_import(start, import.span);
return self.parse_dynamic_import(start, import.span, ImportPhase::Evaluation);
}

tok!("async") => {
Expand Down Expand Up @@ -541,19 +539,27 @@ impl<I: Tokens> Parser<I> {
}

/// `parseImportMetaProperty`
pub(super) fn parse_import_meta_prop(&mut self, import: Import) -> PResult<MetaPropExpr> {
pub(super) fn parse_import_meta_prop(
&mut self,
start: BytePos,
import_span: Span,
) -> PResult<Box<Expr>> {
expect!(self, '.');

let _ = if is!(self, "meta") {
self.parse_ident_name()?
} else {
unexpected!(self, "meta");
};
let ident = self.parse_ident_name()?;

Ok(MetaPropExpr {
span: span!(self, import.span.lo()),
kind: MetaPropKind::ImportMeta,
})
match &*ident.sym {
"meta" => Ok(MetaPropExpr {
span: span!(self, import_span.lo()),
kind: MetaPropKind::ImportMeta,
}
.into()),
"source" => self.parse_dynamic_import(start, import_span, ImportPhase::Source),
// TODO: The proposal doesn't mention import.defer yet because it was
// pending on a decision for import.source. Wait to enable it until it's
// included in the proposal.
_ => unexpected!(self, "meta"),
}
}

/// `is_new_expr`: true iff we are parsing production 'NewExpression'.
Expand Down Expand Up @@ -676,6 +682,7 @@ impl<I: Tokens> Parser<I> {
if eat!(self, "import") {
let base = Callee::Import(Import {
span: span!(self, start),
phase: Default::default(),
});
return self.parse_subscripts(base, true, false);
}
Expand Down Expand Up @@ -1446,16 +1453,28 @@ impl<I: Tokens> Parser<I> {

return Ok((
Box::new(match obj {
Callee::Import(_) => match prop {
MemberProp::Ident(Ident { sym: meta, .. }) if &*meta == "meta" => {
callee @ Callee::Import(_) => match prop {
MemberProp::Ident(Ident { sym, .. }) => {
if !self.ctx().can_be_module {
let span = span!(self, start);
self.emit_err(span, SyntaxError::ImportMetaInScript);
}
Expr::MetaProp(MetaPropExpr {
span,
kind: MetaPropKind::ImportMeta,
})
match &*sym {
"meta" => Expr::MetaProp(MetaPropExpr {
span,
kind: MetaPropKind::ImportMeta,
}),
_ => {
let args = self.parse_args(true)?;

Expr::Call(CallExpr {
span,
callee,
args,
type_args: None,
})
}
}
}
_ => {
unexpected!(self, "meta");
Expand Down Expand Up @@ -1604,6 +1623,7 @@ impl<I: Tokens> Parser<I> {
if eat!(self, "import") {
let obj = Callee::Import(Import {
span: span!(self, start),
phase: Default::default(),
});
return self.parse_subscripts(obj, false, false);
}
Expand Down Expand Up @@ -1648,6 +1668,7 @@ impl<I: Tokens> Parser<I> {
_ if callee.is_ident_ref_to("import") => (
Callee::Import(Import {
span: callee.span(),
phase: Default::default(),
}),
true,
),
Expand Down Expand Up @@ -2071,11 +2092,15 @@ impl<I: Tokens> Parser<I> {
&mut self,
start: BytePos,
import_span: Span,
phase: ImportPhase,
) -> PResult<Box<Expr>> {
let args = self.parse_args(true)?;
let import = Box::new(Expr::Call(CallExpr {
span: span!(self, start),
callee: Callee::Import(Import { span: import_span }),
callee: Callee::Import(Import {
span: import_span,
phase,
}),
args,
type_args: Default::default(),
}));
Expand Down
2 changes: 1 addition & 1 deletion crates/swc_ecma_parser/src/parser/expr/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ fn issue_328() {
span,
expr: Box::new(Expr::Call(CallExpr {
span,
callee: Callee::Import(Import { span }),
callee: Callee::Import(Import { span, phase: Default::default() }),
args: vec![ExprOrSpread {
spread: None,
expr: Box::new(Expr::Lit(Lit::Str(Str {
Expand Down
6 changes: 5 additions & 1 deletion crates/swc_ecma_transforms_module/src/amd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,11 @@ where
match n {
Expr::Call(CallExpr {
span,
callee: Callee::Import(Import { span: import_span }),
callee:
Callee::Import(Import {
span: import_span,
phase: ImportPhase::Evaluation,
}),
args,
..
}) if !self.config.ignore_dynamic => {
Expand Down
6 changes: 5 additions & 1 deletion crates/swc_ecma_transforms_module/src/common_js.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,11 @@ where
match n {
Expr::Call(CallExpr {
span,
callee: Callee::Import(Import { span: import_span }),
callee:
Callee::Import(Import {
span: import_span,
phase: ImportPhase::Evaluation,
}),
args,
..
}) if !self.config.ignore_dynamic => {
Expand Down
1 change: 1 addition & 0 deletions crates/swc_ecma_visit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,7 @@ define!({
}
pub struct Import {
pub span: Span,
pub phase: ImportPhase,
}
pub struct ExprOrSpread {
pub spread: Option<Span>,
Expand Down
2 changes: 2 additions & 0 deletions crates/swc_estree_compat/src/swcify/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,8 @@ impl Swcify for BabelImport {
fn swcify(self, ctx: &Context) -> Self::Output {
Import {
span: ctx.span(&self.base),
// TODO
phase: Default::default(),
}
}
}
Expand Down

0 comments on commit 998d44d

Please sign in to comment.