mirror of
https://github.com/swc-project/swc.git
synced 2024-11-22 15:25:01 +03:00
refactor(*): Fix some clippy warnings (#3257)
This commit is contained in:
parent
214427157d
commit
15b604b6d6
2
clippy.toml
Normal file
2
clippy.toml
Normal file
@ -0,0 +1,2 @@
|
||||
cognitive-complexity-threshold = 50
|
||||
type-complexity-threshold = 25000
|
@ -157,14 +157,10 @@ impl VisitMut for Normalizer {
|
||||
fn visit_mut_stmt(&mut self, s: &mut Stmt) {
|
||||
s.visit_mut_children_with(self);
|
||||
|
||||
match s {
|
||||
Stmt::Decl(Decl::Var(v)) => {
|
||||
if v.decls.is_empty() {
|
||||
s.take();
|
||||
}
|
||||
if let Stmt::Decl(Decl::Var(v)) = s {
|
||||
if v.decls.is_empty() {
|
||||
s.take();
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -182,14 +178,10 @@ impl VisitMut for BeforeDiffNormalizer {
|
||||
fn visit_mut_stmt(&mut self, s: &mut Stmt) {
|
||||
s.visit_mut_children_with(self);
|
||||
|
||||
match s {
|
||||
Stmt::Block(bs) => {
|
||||
if bs.stmts.len() == 1 {
|
||||
*s = bs.stmts[0].take();
|
||||
}
|
||||
if let Stmt::Block(bs) = s {
|
||||
if bs.stmts.len() == 1 {
|
||||
*s = bs.stmts[0].take();
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,18 +69,12 @@ impl DependencyCollector {
|
||||
.unwrap()
|
||||
.insert(name.clone(), Arc::new(ModuleData { fm: fm.clone() }));
|
||||
|
||||
match &*name {
|
||||
FileName::Real(name) => match name.extension() {
|
||||
Some(ext) => {
|
||||
if ext == "json" {
|
||||
return Ok(());
|
||||
}
|
||||
if let FileName::Real(name) = &*name {
|
||||
if let Some(ext) = name.extension() {
|
||||
if ext == "json" {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
_ => {}
|
||||
},
|
||||
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
let module = parse(&fm)?;
|
||||
|
@ -175,14 +175,11 @@ impl Runner {
|
||||
fn run(mut self, files: Vec<PathBuf>) -> Result<()> {
|
||||
// Patch one file at a time.
|
||||
for file in files {
|
||||
match file.extension() {
|
||||
Some(ext) => {
|
||||
if ext == "json" {
|
||||
info!("Skipping json file");
|
||||
continue;
|
||||
}
|
||||
if let Some(ext) = file.extension() {
|
||||
if ext == "json" {
|
||||
info!("Skipping json file");
|
||||
continue;
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
|
||||
let _span = span!(Level::ERROR, "patch", file = &*file.display().to_string()).entered();
|
||||
|
@ -26,19 +26,16 @@ impl VisitMut for AddTypes {
|
||||
fn visit_mut_member_expr(&mut self, e: &mut MemberExpr) {
|
||||
e.visit_mut_children_with(self);
|
||||
|
||||
match &*e.obj {
|
||||
Expr::This(..) => {
|
||||
e.obj = Expr::Paren(ParenExpr {
|
||||
if let Expr::This(..) = &*e.obj {
|
||||
e.obj = Expr::Paren(ParenExpr {
|
||||
span: DUMMY_SP,
|
||||
expr: Box::new(Expr::TsAs(TsAsExpr {
|
||||
span: DUMMY_SP,
|
||||
expr: Box::new(Expr::TsAs(TsAsExpr {
|
||||
span: DUMMY_SP,
|
||||
expr: e.obj.clone(),
|
||||
type_ann: any_type(),
|
||||
})),
|
||||
})
|
||||
.into();
|
||||
}
|
||||
_ => {}
|
||||
expr: e.obj.clone(),
|
||||
type_ann: any_type(),
|
||||
})),
|
||||
})
|
||||
.into();
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,15 +70,11 @@ impl VisitMut for AddTypes {
|
||||
v.visit_mut_children_with(self);
|
||||
|
||||
if !self.should_not_annotate_type {
|
||||
match &mut v.name {
|
||||
Pat::Ident(id) => {
|
||||
id.type_ann = Some(TsTypeAnn {
|
||||
span: DUMMY_SP,
|
||||
type_ann: any_type(),
|
||||
});
|
||||
}
|
||||
|
||||
_ => {}
|
||||
if let Pat::Ident(id) = &mut v.name {
|
||||
id.type_ann = Some(TsTypeAnn {
|
||||
span: DUMMY_SP,
|
||||
type_ann: any_type(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,11 +27,8 @@ fn fixture(path: PathBuf) {
|
||||
);
|
||||
let mut p = Parser::new_from(lexer);
|
||||
|
||||
match p.parse_module() {
|
||||
Err(err) => {
|
||||
err.into_diagnostic(&handler).emit();
|
||||
}
|
||||
_ => {}
|
||||
if let Err(err) = p.parse_module() {
|
||||
err.into_diagnostic(&handler).emit();
|
||||
}
|
||||
for err in p.take_errors() {
|
||||
err.into_diagnostic(&handler).emit();
|
||||
|
@ -54,6 +54,7 @@ pub struct JsCompiler {
|
||||
#[napi]
|
||||
impl JsCompiler {
|
||||
#[napi(constructor)]
|
||||
#[allow(clippy::new_without_default)]
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
_compiler: COMPILER.clone(),
|
||||
|
@ -282,7 +282,7 @@ impl NodeResolver {
|
||||
/// Resolve a path as a directory, using the "main" key from a
|
||||
/// package.json file if it exists, or resolving to the
|
||||
/// index.EXT file if it exists.
|
||||
fn resolve_as_directory(&self, path: &PathBuf) -> Result<PathBuf, Error> {
|
||||
fn resolve_as_directory(&self, path: &Path) -> Result<PathBuf, Error> {
|
||||
// 1. If X/package.json is a file, use it.
|
||||
let pkg_path = path.join("package.json");
|
||||
if pkg_path.is_file() {
|
||||
@ -297,12 +297,12 @@ impl NodeResolver {
|
||||
}
|
||||
|
||||
/// Resolve using the package.json "main" key.
|
||||
fn resolve_package_main(&self, _: &PathBuf) -> Result<PathBuf, Error> {
|
||||
fn resolve_package_main(&self, _: &Path) -> Result<PathBuf, Error> {
|
||||
bail!("package.json is not supported")
|
||||
}
|
||||
|
||||
/// Resolve a directory to its index.EXT.
|
||||
fn resolve_index(&self, path: &PathBuf) -> Result<PathBuf, Error> {
|
||||
fn resolve_index(&self, path: &Path) -> Result<PathBuf, Error> {
|
||||
// 1. If X/index.js is a file, load X/index.js as JavaScript text.
|
||||
// 2. If X/index.json is a file, parse X/index.json to a JavaScript object.
|
||||
// 3. If X/index.node is a file, load X/index.node as binary addon.
|
||||
|
@ -183,36 +183,27 @@ where
|
||||
fn visit_mut_call_expr(&mut self, node: &mut CallExpr) {
|
||||
node.visit_mut_children_with(self);
|
||||
|
||||
match &node.callee {
|
||||
Callee::Expr(e) => {
|
||||
match &**e {
|
||||
Expr::Ident(i) => {
|
||||
// TODO: Check for global mark
|
||||
if i.sym == *"require" && node.args.len() == 1 {
|
||||
match &*node.args[0].expr {
|
||||
Expr::Lit(Lit::Str(module_name)) => {
|
||||
if self.bundler.is_external(&module_name.value) {
|
||||
return;
|
||||
}
|
||||
let load = CallExpr {
|
||||
span: node.span,
|
||||
callee: Ident::new("load".into(), i.span).as_callee(),
|
||||
args: vec![],
|
||||
type_args: None,
|
||||
};
|
||||
self.replaced = true;
|
||||
*node = load;
|
||||
|
||||
tracing::trace!("Found, and replacing require");
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
if let Callee::Expr(e) = &node.callee {
|
||||
if let Expr::Ident(i) = &**e {
|
||||
// TODO: Check for global mark
|
||||
if i.sym == *"require" && node.args.len() == 1 {
|
||||
if let Expr::Lit(Lit::Str(module_name)) = &*node.args[0].expr {
|
||||
if self.bundler.is_external(&module_name.value) {
|
||||
return;
|
||||
}
|
||||
let load = CallExpr {
|
||||
span: node.span,
|
||||
callee: Ident::new("load".into(), i.span).as_callee(),
|
||||
args: vec![],
|
||||
type_args: None,
|
||||
};
|
||||
self.replaced = true;
|
||||
*node = load;
|
||||
|
||||
tracing::trace!("Found, and replacing require");
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -223,122 +214,119 @@ where
|
||||
return;
|
||||
}
|
||||
|
||||
match node {
|
||||
ModuleItem::ModuleDecl(ModuleDecl::Import(i)) => {
|
||||
let dep_module_id = self
|
||||
.base
|
||||
.imports
|
||||
.specifiers
|
||||
.iter()
|
||||
.find(|(src, _)| src.src.value == i.src.value)
|
||||
.map(|v| v.0.module_id);
|
||||
let dep_module_id = match dep_module_id {
|
||||
Some(v) => v,
|
||||
_ => {
|
||||
return;
|
||||
if let ModuleItem::ModuleDecl(ModuleDecl::Import(i)) = node {
|
||||
let dep_module_id = self
|
||||
.base
|
||||
.imports
|
||||
.specifiers
|
||||
.iter()
|
||||
.find(|(src, _)| src.src.value == i.src.value)
|
||||
.map(|v| v.0.module_id);
|
||||
let dep_module_id = match dep_module_id {
|
||||
Some(v) => v,
|
||||
_ => {
|
||||
return;
|
||||
}
|
||||
};
|
||||
// Replace imports iff dependency is common js module.
|
||||
let dep_module = self.bundler.scope.get_module(dep_module_id).unwrap();
|
||||
if !self.bundler.scope.is_cjs(dep_module_id) && dep_module.is_es6 {
|
||||
return;
|
||||
}
|
||||
|
||||
let load_var = self.bundler.make_cjs_load_var(&dep_module, i.span);
|
||||
// Replace import progress from 'progress';
|
||||
// Side effect import
|
||||
if i.specifiers.is_empty() {
|
||||
self.replaced = true;
|
||||
*node = ModuleItem::Stmt(
|
||||
CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: load_var.as_callee(),
|
||||
args: vec![],
|
||||
type_args: None,
|
||||
}
|
||||
};
|
||||
// Replace imports iff dependency is common js module.
|
||||
let dep_module = self.bundler.scope.get_module(dep_module_id).unwrap();
|
||||
if !self.bundler.scope.is_cjs(dep_module_id) && dep_module.is_es6 {
|
||||
return;
|
||||
}
|
||||
.into_stmt(),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
let load_var = self.bundler.make_cjs_load_var(&dep_module, i.span);
|
||||
// Replace import progress from 'progress';
|
||||
// Side effect import
|
||||
if i.specifiers.is_empty() {
|
||||
self.replaced = true;
|
||||
*node = ModuleItem::Stmt(
|
||||
CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: load_var.as_callee(),
|
||||
args: vec![],
|
||||
type_args: None,
|
||||
}
|
||||
.into_stmt(),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
let mut props = vec![];
|
||||
// TODO
|
||||
for spec in i.specifiers.clone() {
|
||||
match spec {
|
||||
ImportSpecifier::Named(s) => match s.imported {
|
||||
Some(ModuleExportName::Ident(imported)) => {
|
||||
props.push(ObjectPatProp::KeyValue(KeyValuePatProp {
|
||||
key: imported.into(),
|
||||
value: Box::new(s.local.into()),
|
||||
}));
|
||||
}
|
||||
Some(ModuleExportName::Str(..)) => {
|
||||
unimplemented!("module string names unimplemented")
|
||||
}
|
||||
_ => {
|
||||
props.push(ObjectPatProp::Assign(AssignPatProp {
|
||||
span: s.span,
|
||||
key: s.local,
|
||||
value: None,
|
||||
}));
|
||||
}
|
||||
},
|
||||
ImportSpecifier::Default(s) => {
|
||||
let mut props = vec![];
|
||||
// TODO
|
||||
for spec in i.specifiers.clone() {
|
||||
match spec {
|
||||
ImportSpecifier::Named(s) => match s.imported {
|
||||
Some(ModuleExportName::Ident(imported)) => {
|
||||
props.push(ObjectPatProp::KeyValue(KeyValuePatProp {
|
||||
key: PropName::Ident(Ident::new("default".into(), DUMMY_SP)),
|
||||
key: imported.into(),
|
||||
value: Box::new(s.local.into()),
|
||||
}));
|
||||
}
|
||||
ImportSpecifier::Namespace(ns) => {
|
||||
self.replaced = true;
|
||||
*node = ModuleItem::Stmt(Stmt::Decl(Decl::Var(VarDecl {
|
||||
span: i.span,
|
||||
kind: VarDeclKind::Var,
|
||||
declare: false,
|
||||
decls: vec![VarDeclarator {
|
||||
span: ns.span,
|
||||
name: ns.local.into(),
|
||||
init: Some(Box::new(
|
||||
CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: load_var.as_callee(),
|
||||
args: vec![],
|
||||
type_args: None,
|
||||
}
|
||||
.into(),
|
||||
)),
|
||||
definite: false,
|
||||
}],
|
||||
})));
|
||||
return;
|
||||
Some(ModuleExportName::Str(..)) => {
|
||||
unimplemented!("module string names unimplemented")
|
||||
}
|
||||
_ => {
|
||||
props.push(ObjectPatProp::Assign(AssignPatProp {
|
||||
span: s.span,
|
||||
key: s.local,
|
||||
value: None,
|
||||
}));
|
||||
}
|
||||
},
|
||||
ImportSpecifier::Default(s) => {
|
||||
props.push(ObjectPatProp::KeyValue(KeyValuePatProp {
|
||||
key: PropName::Ident(Ident::new("default".into(), DUMMY_SP)),
|
||||
value: Box::new(s.local.into()),
|
||||
}));
|
||||
}
|
||||
ImportSpecifier::Namespace(ns) => {
|
||||
self.replaced = true;
|
||||
*node = ModuleItem::Stmt(Stmt::Decl(Decl::Var(VarDecl {
|
||||
span: i.span,
|
||||
kind: VarDeclKind::Var,
|
||||
declare: false,
|
||||
decls: vec![VarDeclarator {
|
||||
span: ns.span,
|
||||
name: ns.local.into(),
|
||||
init: Some(Box::new(
|
||||
CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: load_var.as_callee(),
|
||||
args: vec![],
|
||||
type_args: None,
|
||||
}
|
||||
.into(),
|
||||
)),
|
||||
definite: false,
|
||||
}],
|
||||
})));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
self.replaced = true;
|
||||
*node = ModuleItem::Stmt(Stmt::Decl(Decl::Var(VarDecl {
|
||||
span: i.span,
|
||||
kind: VarDeclKind::Var,
|
||||
declare: false,
|
||||
decls: vec![VarDeclarator {
|
||||
span: i.span,
|
||||
name: Pat::Object(ObjectPat {
|
||||
span: DUMMY_SP,
|
||||
props,
|
||||
optional: false,
|
||||
type_ann: None,
|
||||
}),
|
||||
init: Some(Box::new(Expr::Call(CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: load_var.as_callee(),
|
||||
type_args: None,
|
||||
args: vec![],
|
||||
}))),
|
||||
definite: false,
|
||||
}],
|
||||
})));
|
||||
}
|
||||
_ => {}
|
||||
|
||||
self.replaced = true;
|
||||
*node = ModuleItem::Stmt(Stmt::Decl(Decl::Var(VarDecl {
|
||||
span: i.span,
|
||||
kind: VarDeclKind::Var,
|
||||
declare: false,
|
||||
decls: vec![VarDeclarator {
|
||||
span: i.span,
|
||||
name: Pat::Object(ObjectPat {
|
||||
span: DUMMY_SP,
|
||||
props,
|
||||
optional: false,
|
||||
type_ann: None,
|
||||
}),
|
||||
init: Some(Box::new(Expr::Call(CallExpr {
|
||||
span: DUMMY_SP,
|
||||
callee: load_var.as_callee(),
|
||||
type_args: None,
|
||||
args: vec![],
|
||||
}))),
|
||||
definite: false,
|
||||
}],
|
||||
})));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -353,20 +341,17 @@ impl VisitMut for DefaultHandler {
|
||||
fn visit_mut_expr(&mut self, e: &mut Expr) {
|
||||
e.visit_mut_children_with(self);
|
||||
|
||||
match e {
|
||||
Expr::Ident(i) => {
|
||||
if i.sym == js_word!("default") {
|
||||
*e = Expr::Member(MemberExpr {
|
||||
span: i.span,
|
||||
obj: Box::new(Expr::Ident(Ident::new(
|
||||
"module".into(),
|
||||
DUMMY_SP.with_ctxt(self.local_ctxt),
|
||||
))),
|
||||
prop: MemberProp::Ident(quote_ident!("exports")),
|
||||
});
|
||||
}
|
||||
if let Expr::Ident(i) = e {
|
||||
if i.sym == js_word!("default") {
|
||||
*e = Expr::Member(MemberExpr {
|
||||
span: i.span,
|
||||
obj: Box::new(Expr::Ident(Ident::new(
|
||||
"module".into(),
|
||||
DUMMY_SP.with_ctxt(self.local_ctxt),
|
||||
))),
|
||||
prop: MemberProp::Ident(quote_ident!("exports")),
|
||||
});
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,40 +60,36 @@ where
|
||||
..
|
||||
})) if span.ctxt == injected_ctxt => {
|
||||
for s in specifiers {
|
||||
match s {
|
||||
ExportSpecifier::Named(ExportNamedSpecifier {
|
||||
orig,
|
||||
exported: Some(exported),
|
||||
..
|
||||
}) => {
|
||||
let exported = match exported {
|
||||
ModuleExportName::Ident(ident) => ident,
|
||||
ModuleExportName::Str(..) => {
|
||||
unimplemented!("module string names unimplemented")
|
||||
}
|
||||
};
|
||||
if let Some(..) = ctx.transitive_remap.get(&exported.span.ctxt) {
|
||||
let specifier = ExportSpecifier::Named(ExportNamedSpecifier {
|
||||
span: DUMMY_SP,
|
||||
orig: orig.clone(),
|
||||
exported: Some(ModuleExportName::Ident(exported.clone())),
|
||||
is_type_only: false,
|
||||
});
|
||||
additional_items.push((
|
||||
module_id,
|
||||
ModuleItem::ModuleDecl(ModuleDecl::ExportNamed(
|
||||
NamedExport {
|
||||
span: DUMMY_SP.with_ctxt(injected_ctxt),
|
||||
specifiers: vec![specifier],
|
||||
src: None,
|
||||
type_only: false,
|
||||
asserts: None,
|
||||
},
|
||||
)),
|
||||
));
|
||||
if let ExportSpecifier::Named(ExportNamedSpecifier {
|
||||
orig,
|
||||
exported: Some(exported),
|
||||
..
|
||||
}) = s
|
||||
{
|
||||
let exported = match exported {
|
||||
ModuleExportName::Ident(ident) => ident,
|
||||
ModuleExportName::Str(..) => {
|
||||
unimplemented!("module string names unimplemented")
|
||||
}
|
||||
};
|
||||
if let Some(..) = ctx.transitive_remap.get(&exported.span.ctxt) {
|
||||
let specifier = ExportSpecifier::Named(ExportNamedSpecifier {
|
||||
span: DUMMY_SP,
|
||||
orig: orig.clone(),
|
||||
exported: Some(ModuleExportName::Ident(exported.clone())),
|
||||
is_type_only: false,
|
||||
});
|
||||
additional_items.push((
|
||||
module_id,
|
||||
ModuleItem::ModuleDecl(ModuleDecl::ExportNamed(NamedExport {
|
||||
span: DUMMY_SP.with_ctxt(injected_ctxt),
|
||||
specifiers: vec![specifier],
|
||||
src: None,
|
||||
type_only: false,
|
||||
asserts: None,
|
||||
})),
|
||||
));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -117,13 +113,12 @@ where
|
||||
}))),
|
||||
});
|
||||
|
||||
module.iter().for_each(|(_, v)| match v {
|
||||
ModuleItem::ModuleDecl(ModuleDecl::ExportAll(ref export)) => {
|
||||
module.iter().for_each(|(_, v)| {
|
||||
if let ModuleItem::ModuleDecl(ModuleDecl::ExportAll(ref export)) = v {
|
||||
// We handle this later.
|
||||
let mut map = ctx.export_stars_in_wrapped.lock();
|
||||
map.entry(id).or_default().push(export.span.ctxt);
|
||||
}
|
||||
_ => {}
|
||||
});
|
||||
|
||||
let module_fn = Expr::Fn(FnExpr {
|
||||
|
@ -233,14 +233,11 @@ where
|
||||
let mut declared_ids = AHashSet::<_>::default();
|
||||
|
||||
for (_, stmt) in entry.iter() {
|
||||
match stmt {
|
||||
ModuleItem::Stmt(Stmt::Decl(Decl::Var(decl))) => {
|
||||
if decl.span.ctxt == injected_ctxt {
|
||||
let ids: Vec<Id> = find_ids(decl);
|
||||
declared_ids.extend(ids);
|
||||
}
|
||||
if let ModuleItem::Stmt(Stmt::Decl(Decl::Var(decl))) = stmt {
|
||||
if decl.span.ctxt == injected_ctxt {
|
||||
let ids: Vec<Id> = find_ids(decl);
|
||||
declared_ids.extend(ids);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -320,25 +317,20 @@ where
|
||||
// Handle `export *` for wrapped modules.
|
||||
for (module_id, ctxts) in map.drain() {
|
||||
for (_, stmt) in entry.iter() {
|
||||
match stmt {
|
||||
ModuleItem::Stmt(Stmt::Decl(Decl::Var(decl))) => {
|
||||
let ids: Vec<Id> = find_ids(decl);
|
||||
if let ModuleItem::Stmt(Stmt::Decl(Decl::Var(decl))) = stmt {
|
||||
let ids: Vec<Id> = find_ids(decl);
|
||||
|
||||
for id in ids {
|
||||
if *id.sym() == js_word!("default") {
|
||||
continue;
|
||||
}
|
||||
for id in ids {
|
||||
if *id.sym() == js_word!("default") {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ctxts.contains(&id.ctxt()) {
|
||||
additional_props.entry(module_id).or_default().push(
|
||||
PropOrSpread::Prop(Box::new(Prop::Shorthand(
|
||||
id.into_ident(),
|
||||
))),
|
||||
);
|
||||
}
|
||||
if ctxts.contains(&id.ctxt()) {
|
||||
additional_props.entry(module_id).or_default().push(
|
||||
PropOrSpread::Prop(Box::new(Prop::Shorthand(id.into_ident()))),
|
||||
);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -448,10 +440,9 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
export.specifiers.retain(|s| match s {
|
||||
ExportSpecifier::Namespace(_) => false,
|
||||
_ => true,
|
||||
});
|
||||
export
|
||||
.specifiers
|
||||
.retain(|s| !matches!(s, ExportSpecifier::Namespace(_)));
|
||||
|
||||
export.src = None;
|
||||
}
|
||||
@ -493,38 +484,34 @@ where
|
||||
tracing::trace!("Item count = {}", item_count);
|
||||
|
||||
module.retain_mut(|_, item| {
|
||||
match item {
|
||||
// TODO: Handle export default
|
||||
ModuleItem::ModuleDecl(ModuleDecl::ExportNamed(NamedExport {
|
||||
specifiers, ..
|
||||
})) => {
|
||||
specifiers.retain(|s| match s {
|
||||
ExportSpecifier::Named(ExportNamedSpecifier {
|
||||
exported: Some(exported),
|
||||
..
|
||||
}) => {
|
||||
let exported = match exported {
|
||||
ModuleExportName::Ident(ident) => ident,
|
||||
ModuleExportName::Str(..) => {
|
||||
unimplemented!("module string names unimplemented")
|
||||
}
|
||||
};
|
||||
// Default is not exported via `export *`
|
||||
if exported.sym == js_word!("default") {
|
||||
exported.span.ctxt == info.export_ctxt()
|
||||
} else {
|
||||
ctx.is_exported_ctxt(exported.span.ctxt, info.export_ctxt())
|
||||
if let ModuleItem::ModuleDecl(ModuleDecl::ExportNamed(NamedExport {
|
||||
specifiers, ..
|
||||
})) = item
|
||||
{
|
||||
specifiers.retain(|s| match s {
|
||||
ExportSpecifier::Named(ExportNamedSpecifier {
|
||||
exported: Some(exported),
|
||||
..
|
||||
}) => {
|
||||
let exported = match exported {
|
||||
ModuleExportName::Ident(ident) => ident,
|
||||
ModuleExportName::Str(..) => {
|
||||
unimplemented!("module string names unimplemented")
|
||||
}
|
||||
};
|
||||
// Default is not exported via `export *`
|
||||
if exported.sym == js_word!("default") {
|
||||
exported.span.ctxt == info.export_ctxt()
|
||||
} else {
|
||||
ctx.is_exported_ctxt(exported.span.ctxt, info.export_ctxt())
|
||||
}
|
||||
_ => true,
|
||||
});
|
||||
|
||||
if specifiers.is_empty() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
_ => true,
|
||||
});
|
||||
|
||||
_ => {}
|
||||
if specifiers.is_empty() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
@ -1199,93 +1186,84 @@ where
|
||||
let mut new = Vec::with_capacity(stmts.len() + 32);
|
||||
|
||||
for stmt in stmts {
|
||||
match &stmt {
|
||||
ModuleItem::ModuleDecl(ModuleDecl::Import(import)) => {
|
||||
if self.config.external_modules.contains(&import.src.value) {
|
||||
new.push(stmt);
|
||||
continue;
|
||||
}
|
||||
if let ModuleItem::ModuleDecl(ModuleDecl::Import(import)) = &stmt {
|
||||
if self.config.external_modules.contains(&import.src.value) {
|
||||
new.push(stmt);
|
||||
continue;
|
||||
}
|
||||
|
||||
for specifier in &import.specifiers {
|
||||
match specifier {
|
||||
ImportSpecifier::Named(named) => match &named.imported {
|
||||
Some(imported) => {
|
||||
let imporeted_ident = match imported {
|
||||
ModuleExportName::Ident(ident) => ident,
|
||||
ModuleExportName::Str(..) => {
|
||||
unimplemented!("module string names unimplemented")
|
||||
}
|
||||
};
|
||||
vars.push((
|
||||
module_id,
|
||||
imporeted_ident
|
||||
.clone()
|
||||
.assign_to(named.local.clone())
|
||||
.into_module_item(
|
||||
injected_ctxt,
|
||||
"from_replace_import_specifiers",
|
||||
),
|
||||
));
|
||||
continue;
|
||||
}
|
||||
None => {}
|
||||
},
|
||||
ImportSpecifier::Default(default) => {
|
||||
if let Some((src, _)) = info
|
||||
.imports
|
||||
.specifiers
|
||||
.iter()
|
||||
.find(|s| s.0.src.value == import.src.value)
|
||||
{
|
||||
let imported = Ident::new(
|
||||
js_word!("default"),
|
||||
DUMMY_SP.with_ctxt(src.export_ctxt),
|
||||
);
|
||||
vars.push((
|
||||
module_id,
|
||||
imported
|
||||
.assign_to(default.local.clone())
|
||||
.into_module_item(
|
||||
injected_ctxt,
|
||||
"from_replace_import_specifiers",
|
||||
),
|
||||
));
|
||||
continue;
|
||||
}
|
||||
for specifier in &import.specifiers {
|
||||
match specifier {
|
||||
ImportSpecifier::Named(named) => match &named.imported {
|
||||
Some(imported) => {
|
||||
let imporeted_ident = match imported {
|
||||
ModuleExportName::Ident(ident) => ident,
|
||||
ModuleExportName::Str(..) => {
|
||||
unimplemented!("module string names unimplemented")
|
||||
}
|
||||
};
|
||||
vars.push((
|
||||
module_id,
|
||||
imporeted_ident
|
||||
.clone()
|
||||
.assign_to(named.local.clone())
|
||||
.into_module_item(
|
||||
injected_ctxt,
|
||||
"from_replace_import_specifiers",
|
||||
),
|
||||
));
|
||||
continue;
|
||||
}
|
||||
ImportSpecifier::Namespace(s) => {
|
||||
if let Some((src, _)) = info
|
||||
.imports
|
||||
.specifiers
|
||||
.iter()
|
||||
.find(|s| s.0.src.value == import.src.value)
|
||||
{
|
||||
let esm_id =
|
||||
self.scope.wrapped_esm_id(src.module_id).expect(
|
||||
"If a namespace import specifier is preserved, it \
|
||||
means failure of deblobbing and as a result \
|
||||
module should be marked as wrapped esm",
|
||||
);
|
||||
vars.push((
|
||||
module_id,
|
||||
esm_id
|
||||
.clone()
|
||||
.assign_to(s.local.clone())
|
||||
.into_module_item(
|
||||
injected_ctxt,
|
||||
"from_replace_import_specifiers: namespaced",
|
||||
),
|
||||
));
|
||||
continue;
|
||||
}
|
||||
None => {}
|
||||
},
|
||||
ImportSpecifier::Default(default) => {
|
||||
if let Some((src, _)) = info
|
||||
.imports
|
||||
.specifiers
|
||||
.iter()
|
||||
.find(|s| s.0.src.value == import.src.value)
|
||||
{
|
||||
let imported = Ident::new(
|
||||
js_word!("default"),
|
||||
DUMMY_SP.with_ctxt(src.export_ctxt),
|
||||
);
|
||||
vars.push((
|
||||
module_id,
|
||||
imported.assign_to(default.local.clone()).into_module_item(
|
||||
injected_ctxt,
|
||||
"from_replace_import_specifiers",
|
||||
),
|
||||
));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ImportSpecifier::Namespace(s) => {
|
||||
if let Some((src, _)) = info
|
||||
.imports
|
||||
.specifiers
|
||||
.iter()
|
||||
.find(|s| s.0.src.value == import.src.value)
|
||||
{
|
||||
let esm_id = self.scope.wrapped_esm_id(src.module_id).expect(
|
||||
"If a namespace import specifier is preserved, it means \
|
||||
failure of deblobbing and as a result module should be \
|
||||
marked as wrapped esm",
|
||||
);
|
||||
vars.push((
|
||||
module_id,
|
||||
esm_id.clone().assign_to(s.local.clone()).into_module_item(
|
||||
injected_ctxt,
|
||||
"from_replace_import_specifiers: namespaced",
|
||||
),
|
||||
));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We should remove imports
|
||||
continue;
|
||||
}
|
||||
_ => {}
|
||||
|
||||
// We should remove imports
|
||||
continue;
|
||||
}
|
||||
|
||||
new.push(stmt);
|
||||
@ -1388,6 +1366,19 @@ struct ImportMetaHandler<'a, 'b> {
|
||||
}
|
||||
|
||||
impl VisitMut for ImportMetaHandler<'_, '_> {
|
||||
fn visit_mut_expr(&mut self, e: &mut Expr) {
|
||||
e.visit_mut_children_with(self);
|
||||
|
||||
if let Expr::MetaProp(MetaPropExpr {
|
||||
kind: MetaPropKind::ImportMeta,
|
||||
..
|
||||
}) = e
|
||||
{
|
||||
*e = Expr::Ident(self.inline_ident.clone());
|
||||
self.occurred = true;
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_mut_module(&mut self, n: &mut Module) {
|
||||
n.visit_mut_children_with(self);
|
||||
|
||||
@ -1426,19 +1417,4 @@ impl VisitMut for ImportMetaHandler<'_, '_> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_mut_expr(&mut self, e: &mut Expr) {
|
||||
e.visit_mut_children_with(self);
|
||||
|
||||
match e {
|
||||
Expr::MetaProp(MetaPropExpr {
|
||||
kind: MetaPropKind::ImportMeta,
|
||||
..
|
||||
}) => {
|
||||
*e = Expr::Ident(self.inline_ident.clone());
|
||||
self.occurred = true;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -51,9 +51,8 @@ where
|
||||
let mut analyzer = GraphAnalyzer::new(&self.scope);
|
||||
|
||||
for (name, module) in entries {
|
||||
match builder.kinds.insert(module.id, BundleKind::Named { name }) {
|
||||
Some(v) => bail!("Multiple entries with same input path detected: {:?}", v),
|
||||
None => {}
|
||||
if let Some(v) = builder.kinds.insert(module.id, BundleKind::Named { name }) {
|
||||
bail!("Multiple entries with same input path detected: {:?}", v)
|
||||
}
|
||||
|
||||
analyzer.load(module.id);
|
||||
|
@ -225,25 +225,22 @@ where
|
||||
match &mut e.callee {
|
||||
Callee::Expr(callee)
|
||||
if self.bundler.config.require
|
||||
&& match &**callee {
|
||||
&& matches!(
|
||||
&**callee,
|
||||
Expr::Ident(Ident {
|
||||
sym: js_word!("require"),
|
||||
..
|
||||
}) => true,
|
||||
_ => false,
|
||||
} =>
|
||||
})
|
||||
) =>
|
||||
{
|
||||
if self.bundler.is_external(&src.value) {
|
||||
return;
|
||||
}
|
||||
match &mut **callee {
|
||||
Expr::Ident(i) => {
|
||||
self.mark_as_cjs(&src.value);
|
||||
if let Some((_, export_ctxt)) = self.ctxt_for(&src.value) {
|
||||
i.span = i.span.with_ctxt(export_ctxt);
|
||||
}
|
||||
if let Expr::Ident(i) = &mut **callee {
|
||||
self.mark_as_cjs(&src.value);
|
||||
if let Some((_, export_ctxt)) = self.ctxt_for(&src.value) {
|
||||
i.span = i.span.with_ctxt(export_ctxt);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let span = callee.span();
|
||||
@ -285,66 +282,58 @@ where
|
||||
}
|
||||
|
||||
fn analyze_usage(&mut self, e: &mut Expr) {
|
||||
match e {
|
||||
Expr::Member(e) => match &*e.obj {
|
||||
Expr::Ident(obj) => {
|
||||
if !self.imported_idents.contains_key(&obj.to_id()) {
|
||||
// If it's not imported, just abort the usage analysis.
|
||||
return;
|
||||
}
|
||||
|
||||
if e.prop.is_computed() {
|
||||
// If a module is accessed with unknown key, we should import
|
||||
// everything from it.
|
||||
self.add_forced_ns_for(obj.to_id());
|
||||
return;
|
||||
}
|
||||
|
||||
// Store usages of obj
|
||||
let import = self.info.imports.iter().find(|import| {
|
||||
for s in &import.specifiers {
|
||||
match s {
|
||||
ImportSpecifier::Namespace(n) => {
|
||||
return obj.sym == n.local.sym
|
||||
&& (obj.span.ctxt == self.module_ctxt
|
||||
|| obj.span.ctxt == n.local.span.ctxt)
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
});
|
||||
let import = match import {
|
||||
Some(v) => v,
|
||||
None => return,
|
||||
};
|
||||
|
||||
let mark = self.ctxt_for(&import.src.value);
|
||||
let exported_ctxt = match mark {
|
||||
None => return,
|
||||
Some(ctxts) => ctxts.1,
|
||||
};
|
||||
let prop = match &e.prop {
|
||||
MemberProp::Ident(i) => {
|
||||
let mut i = i.clone();
|
||||
i.span = i.span.with_ctxt(exported_ctxt);
|
||||
i
|
||||
}
|
||||
_ => unreachable!(
|
||||
"Non-computed member expression with property other than ident is \
|
||||
invalid"
|
||||
),
|
||||
};
|
||||
|
||||
self.usages
|
||||
.entry(obj.to_id())
|
||||
.or_default()
|
||||
.push(prop.to_id());
|
||||
if let Expr::Member(e) = e {
|
||||
if let Expr::Ident(obj) = &*e.obj {
|
||||
if !self.imported_idents.contains_key(&obj.to_id()) {
|
||||
// If it's not imported, just abort the usage analysis.
|
||||
return;
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
|
||||
if e.prop.is_computed() {
|
||||
// If a module is accessed with unknown key, we should import
|
||||
// everything from it.
|
||||
self.add_forced_ns_for(obj.to_id());
|
||||
return;
|
||||
}
|
||||
|
||||
// Store usages of obj
|
||||
let import = self.info.imports.iter().find(|import| {
|
||||
for s in &import.specifiers {
|
||||
if let ImportSpecifier::Namespace(n) = s {
|
||||
return obj.sym == n.local.sym
|
||||
&& (obj.span.ctxt == self.module_ctxt
|
||||
|| obj.span.ctxt == n.local.span.ctxt);
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
});
|
||||
let import = match import {
|
||||
Some(v) => v,
|
||||
None => return,
|
||||
};
|
||||
|
||||
let mark = self.ctxt_for(&import.src.value);
|
||||
let exported_ctxt = match mark {
|
||||
None => return,
|
||||
Some(ctxts) => ctxts.1,
|
||||
};
|
||||
let prop = match &e.prop {
|
||||
MemberProp::Ident(i) => {
|
||||
let mut i = i.clone();
|
||||
i.span = i.span.with_ctxt(exported_ctxt);
|
||||
i
|
||||
}
|
||||
_ => unreachable!(
|
||||
"Non-computed member expression with property other than ident is invalid"
|
||||
),
|
||||
};
|
||||
|
||||
self.usages
|
||||
.entry(obj.to_id())
|
||||
.or_default()
|
||||
.push(prop.to_id());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -386,6 +375,53 @@ where
|
||||
{
|
||||
noop_visit_mut_type!();
|
||||
|
||||
fn visit_mut_export_named_specifier(&mut self, s: &mut ExportNamedSpecifier) {
|
||||
let orig = match &s.orig {
|
||||
ModuleExportName::Ident(ident) => ident,
|
||||
ModuleExportName::Str(..) => unimplemented!("module string names unimplemented"),
|
||||
};
|
||||
|
||||
self.add_forced_ns_for(orig.to_id());
|
||||
|
||||
match &mut s.exported {
|
||||
Some(ModuleExportName::Ident(exported)) => {
|
||||
// PR 3139 (https://github.com/swc-project/swc/pull/3139) removes the syntax context from any named exports from other sources.
|
||||
exported.span.ctxt = self.module_ctxt;
|
||||
}
|
||||
Some(ModuleExportName::Str(..)) => unimplemented!("module string names unimplemented"),
|
||||
None => {
|
||||
let exported = Ident::new(orig.sym.clone(), orig.span.with_ctxt(self.module_ctxt));
|
||||
s.exported = Some(ModuleExportName::Ident(exported));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_mut_expr(&mut self, e: &mut Expr) {
|
||||
e.visit_mut_children_with(self);
|
||||
|
||||
if !self.deglob_phase {
|
||||
// Firstly, we check for usages of imported namespaces.
|
||||
// Code like below are handled by this check.
|
||||
//
|
||||
// import * as log from './log';
|
||||
// console.log(log)
|
||||
// console.log(log.getLogger())
|
||||
if !self.in_obj_of_member {
|
||||
if let Expr::Ident(i) = &e {
|
||||
if !self.in_obj_of_member {
|
||||
self.add_forced_ns_for(i.to_id());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.analyze_usage(e);
|
||||
self.find_require(e);
|
||||
} else {
|
||||
self.try_deglob(e);
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_mut_import_decl(&mut self, import: &mut ImportDecl) {
|
||||
// Ignore if it's a core module.
|
||||
if self.bundler.is_external(&import.src.value) {
|
||||
@ -440,80 +476,47 @@ where
|
||||
|
||||
// deglob namespace imports
|
||||
if import.specifiers.len() == 1 {
|
||||
match &import.specifiers[0] {
|
||||
ImportSpecifier::Namespace(ns) => {
|
||||
//
|
||||
let specifiers = self
|
||||
.usages
|
||||
.get(&ns.local.to_id())
|
||||
.cloned()
|
||||
.map(|ids| {
|
||||
//
|
||||
let specifiers: Vec<_> = ids
|
||||
.into_iter()
|
||||
.map(|id| {
|
||||
self.idents_to_deglob.insert(id.clone());
|
||||
ImportSpecifier::Named(ImportNamedSpecifier {
|
||||
span: DUMMY_SP,
|
||||
local: Ident::new(id.0, DUMMY_SP.with_ctxt(id.1)),
|
||||
imported: None,
|
||||
is_type_only: false,
|
||||
})
|
||||
if let ImportSpecifier::Namespace(ns) = &import.specifiers[0] {
|
||||
//
|
||||
let specifiers = self
|
||||
.usages
|
||||
.get(&ns.local.to_id())
|
||||
.cloned()
|
||||
.map(|ids| {
|
||||
//
|
||||
let specifiers: Vec<_> = ids
|
||||
.into_iter()
|
||||
.map(|id| {
|
||||
self.idents_to_deglob.insert(id.clone());
|
||||
ImportSpecifier::Named(ImportNamedSpecifier {
|
||||
span: DUMMY_SP,
|
||||
local: Ident::new(id.0, DUMMY_SP.with_ctxt(id.1)),
|
||||
imported: None,
|
||||
is_type_only: false,
|
||||
})
|
||||
.collect();
|
||||
})
|
||||
.collect();
|
||||
|
||||
for import_info in &mut self.info.imports {
|
||||
if import_info.src != import.src {
|
||||
continue;
|
||||
}
|
||||
|
||||
import_info.specifiers.extend(specifiers.clone());
|
||||
for import_info in &mut self.info.imports {
|
||||
if import_info.src != import.src {
|
||||
continue;
|
||||
}
|
||||
|
||||
specifiers
|
||||
})
|
||||
.unwrap_or_else(Vec::new);
|
||||
|
||||
if !specifiers.is_empty() {
|
||||
import.specifiers = specifiers;
|
||||
return;
|
||||
}
|
||||
|
||||
// We failed to found property usage.
|
||||
self.info.forced_ns.insert(import.src.value.clone());
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_mut_expr(&mut self, e: &mut Expr) {
|
||||
e.visit_mut_children_with(self);
|
||||
|
||||
if !self.deglob_phase {
|
||||
// Firstly, we check for usages of imported namespaces.
|
||||
// Code like below are handled by this check.
|
||||
//
|
||||
// import * as log from './log';
|
||||
// console.log(log)
|
||||
// console.log(log.getLogger())
|
||||
if !self.in_obj_of_member {
|
||||
match &e {
|
||||
Expr::Ident(i) => {
|
||||
if !self.in_obj_of_member {
|
||||
self.add_forced_ns_for(i.to_id());
|
||||
return;
|
||||
import_info.specifiers.extend(specifiers.clone());
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
self.analyze_usage(e);
|
||||
self.find_require(e);
|
||||
} else {
|
||||
self.try_deglob(e);
|
||||
specifiers
|
||||
})
|
||||
.unwrap_or_else(Vec::new);
|
||||
|
||||
if !specifiers.is_empty() {
|
||||
import.specifiers = specifiers;
|
||||
return;
|
||||
}
|
||||
|
||||
// We failed to found property usage.
|
||||
self.info.forced_ns.insert(import.src.value.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -530,6 +533,52 @@ where
|
||||
self.in_obj_of_member = old;
|
||||
}
|
||||
|
||||
fn visit_mut_module_items(&mut self, items: &mut Vec<ModuleItem>) {
|
||||
self.top_level = true;
|
||||
items.visit_mut_children_with(self);
|
||||
|
||||
items.retain_mut(|item| match item {
|
||||
ModuleItem::Stmt(Stmt::Empty(..)) => false,
|
||||
ModuleItem::Stmt(Stmt::Decl(Decl::Var(var))) => {
|
||||
var.decls.retain(|d| !matches!(d.name, Pat::Invalid(..)));
|
||||
|
||||
!var.decls.is_empty()
|
||||
}
|
||||
|
||||
_ => true,
|
||||
});
|
||||
|
||||
if self.deglob_phase {
|
||||
let mut wrapping_required = vec![];
|
||||
for import in self.info.imports.iter_mut() {
|
||||
let use_ns = self.info.forced_ns.contains(&import.src.value)
|
||||
|| self
|
||||
.bundler
|
||||
.config
|
||||
.external_modules
|
||||
.contains(&import.src.value);
|
||||
|
||||
if use_ns {
|
||||
wrapping_required.push(import.src.value.clone());
|
||||
} else {
|
||||
// De-glob namespace imports
|
||||
import
|
||||
.specifiers
|
||||
.retain(|s| !matches!(s, ImportSpecifier::Namespace(_)));
|
||||
}
|
||||
}
|
||||
|
||||
for id in wrapping_required {
|
||||
self.mark_as_wrapping_required(&id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_mut_stmts(&mut self, items: &mut Vec<Stmt>) {
|
||||
self.top_level = false;
|
||||
items.visit_mut_children_with(self)
|
||||
}
|
||||
|
||||
fn visit_mut_super_prop_expr(&mut self, e: &mut SuperPropExpr) {
|
||||
let old = self.in_obj_of_member;
|
||||
|
||||
@ -541,32 +590,6 @@ where
|
||||
self.in_obj_of_member = old;
|
||||
}
|
||||
|
||||
fn visit_mut_stmts(&mut self, items: &mut Vec<Stmt>) {
|
||||
self.top_level = false;
|
||||
items.visit_mut_children_with(self)
|
||||
}
|
||||
|
||||
fn visit_mut_export_named_specifier(&mut self, s: &mut ExportNamedSpecifier) {
|
||||
let orig = match &s.orig {
|
||||
ModuleExportName::Ident(ident) => ident,
|
||||
ModuleExportName::Str(..) => unimplemented!("module string names unimplemented"),
|
||||
};
|
||||
|
||||
self.add_forced_ns_for(orig.to_id());
|
||||
|
||||
match &mut s.exported {
|
||||
Some(ModuleExportName::Ident(exported)) => {
|
||||
// PR 3139 (https://github.com/swc-project/swc/pull/3139) removes the syntax context from any named exports from other sources.
|
||||
exported.span.ctxt = self.module_ctxt;
|
||||
}
|
||||
Some(ModuleExportName::Str(..)) => unimplemented!("module string names unimplemented"),
|
||||
None => {
|
||||
let exported = Ident::new(orig.sym.clone(), orig.span.with_ctxt(self.module_ctxt));
|
||||
s.exported = Some(ModuleExportName::Ident(exported));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// ```js
|
||||
/// const { readFile } = required('fs');
|
||||
/// ```
|
||||
@ -579,21 +602,21 @@ where
|
||||
fn visit_mut_var_declarator(&mut self, node: &mut VarDeclarator) {
|
||||
node.visit_mut_children_with(self);
|
||||
|
||||
match &mut node.init {
|
||||
Some(init) => match &mut **init {
|
||||
if let Some(init) = &mut node.init {
|
||||
match &mut **init {
|
||||
Expr::Call(CallExpr {
|
||||
span,
|
||||
callee: Callee::Expr(ref mut callee),
|
||||
ref args,
|
||||
..
|
||||
}) if self.bundler.config.require
|
||||
&& match &**callee {
|
||||
&& matches!(
|
||||
&**callee,
|
||||
Expr::Ident(Ident {
|
||||
sym: js_word!("require"),
|
||||
..
|
||||
}) => true,
|
||||
_ => false,
|
||||
}
|
||||
})
|
||||
)
|
||||
&& args.len() == 1 =>
|
||||
{
|
||||
let span = *span;
|
||||
@ -611,13 +634,10 @@ where
|
||||
|
||||
self.mark_as_cjs(&src.value);
|
||||
|
||||
match &mut **callee {
|
||||
Expr::Ident(i) => {
|
||||
if let Some((_, export_ctxt)) = self.ctxt_for(&src.value) {
|
||||
i.span = i.span.with_ctxt(export_ctxt);
|
||||
}
|
||||
if let Expr::Ident(i) = &mut **callee {
|
||||
if let Some((_, export_ctxt)) = self.ctxt_for(&src.value) {
|
||||
i.span = i.span.with_ctxt(export_ctxt);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let ids: Vec<Ident> = find_ids(&node.name);
|
||||
@ -651,53 +671,6 @@ where
|
||||
}
|
||||
|
||||
_ => {}
|
||||
},
|
||||
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_mut_module_items(&mut self, items: &mut Vec<ModuleItem>) {
|
||||
self.top_level = true;
|
||||
items.visit_mut_children_with(self);
|
||||
|
||||
items.retain_mut(|item| match item {
|
||||
ModuleItem::Stmt(Stmt::Empty(..)) => false,
|
||||
ModuleItem::Stmt(Stmt::Decl(Decl::Var(var))) => {
|
||||
var.decls.retain(|d| match d.name {
|
||||
Pat::Invalid(..) => false,
|
||||
_ => true,
|
||||
});
|
||||
|
||||
!var.decls.is_empty()
|
||||
}
|
||||
|
||||
_ => true,
|
||||
});
|
||||
|
||||
if self.deglob_phase {
|
||||
let mut wrapping_required = vec![];
|
||||
for import in self.info.imports.iter_mut() {
|
||||
let use_ns = self.info.forced_ns.contains(&import.src.value)
|
||||
|| self
|
||||
.bundler
|
||||
.config
|
||||
.external_modules
|
||||
.contains(&import.src.value);
|
||||
|
||||
if use_ns {
|
||||
wrapping_required.push(import.src.value.clone());
|
||||
} else {
|
||||
// De-glob namespace imports
|
||||
import.specifiers.retain(|s| match s {
|
||||
ImportSpecifier::Namespace(_) => false,
|
||||
_ => true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
for id in wrapping_required {
|
||||
self.mark_as_wrapping_required(&id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -60,14 +60,11 @@ impl VisitMut for KeywordRenamer {
|
||||
}
|
||||
|
||||
fn visit_mut_expr(&mut self, n: &mut Expr) {
|
||||
match n {
|
||||
Expr::Ident(n) => {
|
||||
if let Some(renamed) = self.renamed(n) {
|
||||
*n = renamed;
|
||||
}
|
||||
return;
|
||||
if let Expr::Ident(n) = n {
|
||||
if let Some(renamed) = self.renamed(n) {
|
||||
*n = renamed;
|
||||
}
|
||||
_ => {}
|
||||
return;
|
||||
}
|
||||
|
||||
n.visit_mut_children_with(self);
|
||||
@ -97,44 +94,38 @@ impl VisitMut for KeywordRenamer {
|
||||
fn visit_mut_object_pat_prop(&mut self, n: &mut ObjectPatProp) {
|
||||
n.visit_mut_children_with(self);
|
||||
|
||||
match n {
|
||||
ObjectPatProp::Assign(pat) => {
|
||||
if let Some(renamed) = self.renamed(&pat.key) {
|
||||
match &mut pat.value {
|
||||
Some(default) => {
|
||||
*n = ObjectPatProp::KeyValue(KeyValuePatProp {
|
||||
key: PropName::Ident(pat.key.take()),
|
||||
value: Box::new(Pat::Assign(AssignPat {
|
||||
span: pat.span,
|
||||
left: Box::new(Pat::Ident(renamed.into())),
|
||||
right: default.take(),
|
||||
type_ann: None,
|
||||
})),
|
||||
});
|
||||
}
|
||||
None => {
|
||||
*n = ObjectPatProp::KeyValue(KeyValuePatProp {
|
||||
key: PropName::Ident(pat.key.take()),
|
||||
value: Box::new(Pat::Ident(renamed.into())),
|
||||
})
|
||||
}
|
||||
if let ObjectPatProp::Assign(pat) = n {
|
||||
if let Some(renamed) = self.renamed(&pat.key) {
|
||||
match &mut pat.value {
|
||||
Some(default) => {
|
||||
*n = ObjectPatProp::KeyValue(KeyValuePatProp {
|
||||
key: PropName::Ident(pat.key.take()),
|
||||
value: Box::new(Pat::Assign(AssignPat {
|
||||
span: pat.span,
|
||||
left: Box::new(Pat::Ident(renamed.into())),
|
||||
right: default.take(),
|
||||
type_ann: None,
|
||||
})),
|
||||
});
|
||||
}
|
||||
None => {
|
||||
*n = ObjectPatProp::KeyValue(KeyValuePatProp {
|
||||
key: PropName::Ident(pat.key.take()),
|
||||
value: Box::new(Pat::Ident(renamed.into())),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_mut_pat(&mut self, n: &mut Pat) {
|
||||
match n {
|
||||
Pat::Ident(n) => {
|
||||
if let Some(renamed) = self.renamed(&n.id) {
|
||||
*n = renamed.into();
|
||||
}
|
||||
|
||||
return;
|
||||
if let Pat::Ident(n) = n {
|
||||
if let Some(renamed) = self.renamed(&n.id) {
|
||||
*n = renamed.into();
|
||||
}
|
||||
_ => {}
|
||||
|
||||
return;
|
||||
}
|
||||
n.visit_mut_children_with(self);
|
||||
}
|
||||
|
@ -428,15 +428,15 @@ impl Visit for Es6ModuleDetector {
|
||||
e.visit_children_with(self);
|
||||
|
||||
match &e.callee {
|
||||
Callee::Expr(e) => match &**e {
|
||||
Expr::Ident(Ident {
|
||||
Callee::Expr(e) => {
|
||||
if let Expr::Ident(Ident {
|
||||
sym: js_word!("require"),
|
||||
..
|
||||
}) => {
|
||||
}) = &**e
|
||||
{
|
||||
self.found_other = true;
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
}
|
||||
Callee::Super(_) | Callee::Import(_) => {}
|
||||
}
|
||||
}
|
||||
|
@ -27,10 +27,7 @@ pub(crate) fn inline(injected_ctxt: SyntaxContext, module: &mut Modules) {
|
||||
|
||||
let mut v = Inliner { data: data.into() };
|
||||
module.par_visit_mut_with(&mut v);
|
||||
module.retain_mut(|_, s| match s {
|
||||
ModuleItem::Stmt(Stmt::Empty(..)) => false,
|
||||
_ => true,
|
||||
});
|
||||
module.retain_mut(|_, s| !matches!(s, ModuleItem::Stmt(Stmt::Empty(..))));
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -78,11 +75,8 @@ impl Visit for Analyzer<'_> {
|
||||
|
||||
fn visit_var_declarator(&mut self, n: &VarDeclarator) {
|
||||
n.visit_children_with(self);
|
||||
match (&n.name, n.init.as_deref()) {
|
||||
(Pat::Ident(from), Some(Expr::Ident(to))) => {
|
||||
self.store(from.id.clone().into(), to.into());
|
||||
}
|
||||
_ => {}
|
||||
if let (Pat::Ident(from), Some(Expr::Ident(to))) = (&n.name, n.init.as_deref()) {
|
||||
self.store(from.id.clone().into(), to.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -124,10 +118,7 @@ impl VisitMut for Inliner {
|
||||
fn visit_mut_module_items(&mut self, n: &mut Vec<ModuleItem>) {
|
||||
n.visit_mut_children_with(self);
|
||||
|
||||
n.retain(|v| match v {
|
||||
ModuleItem::Stmt(Stmt::Empty(..)) => false,
|
||||
_ => true,
|
||||
});
|
||||
n.retain(|v| !matches!(v, ModuleItem::Stmt(Stmt::Empty(..))));
|
||||
}
|
||||
|
||||
fn visit_mut_prop(&mut self, n: &mut Prop) {
|
||||
@ -176,13 +167,10 @@ impl VisitMut for Inliner {
|
||||
|
||||
fn visit_mut_var_declarators(&mut self, n: &mut Vec<VarDeclarator>) {
|
||||
n.retain(|d| {
|
||||
match &d.name {
|
||||
Pat::Ident(name) => {
|
||||
if self.data.ids.contains_key(&name.id.clone().into()) {
|
||||
return false;
|
||||
}
|
||||
if let Pat::Ident(name) = &d.name {
|
||||
if self.data.ids.contains_key(&name.id.clone().into()) {
|
||||
return false;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
true
|
||||
|
@ -93,11 +93,11 @@ impl StmtDepGraph {
|
||||
self.inner.edge_weight(a, b).cloned()
|
||||
}
|
||||
|
||||
pub fn neighbors_directed<'a>(
|
||||
&'a self,
|
||||
pub fn neighbors_directed(
|
||||
&self,
|
||||
start: usize,
|
||||
dir: EdgeDirection,
|
||||
) -> impl 'a + Iterator<Item = usize> {
|
||||
) -> impl '_ + Iterator<Item = usize> {
|
||||
self.inner.neighbors_directed(start, dir)
|
||||
}
|
||||
|
||||
|
@ -330,24 +330,23 @@ fn iter<'a>(
|
||||
|
||||
/// Using prototype should be treated as an initialization.
|
||||
#[derive(Default)]
|
||||
struct FieldInitFinter {
|
||||
struct FieldInitFinder {
|
||||
in_object_assign: bool,
|
||||
in_rhs: bool,
|
||||
accessed: AHashSet<Id>,
|
||||
}
|
||||
|
||||
impl FieldInitFinter {
|
||||
impl FieldInitFinder {
|
||||
fn check_lhs_of_assign(&mut self, lhs: &PatOrExpr) {
|
||||
match lhs {
|
||||
PatOrExpr::Expr(e) => {
|
||||
self.check_lhs_expr_of_assign(e);
|
||||
}
|
||||
PatOrExpr::Pat(pat) => match &**pat {
|
||||
Pat::Expr(e) => {
|
||||
PatOrExpr::Pat(pat) => {
|
||||
if let Pat::Expr(e) = &**pat {
|
||||
self.check_lhs_expr_of_assign(e);
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
fn check_lhs_expr_of_assign(&mut self, lhs: &Expr) {
|
||||
@ -364,7 +363,7 @@ impl FieldInitFinter {
|
||||
}
|
||||
}
|
||||
|
||||
impl Visit for FieldInitFinter {
|
||||
impl Visit for FieldInitFinder {
|
||||
noop_visit_type!();
|
||||
|
||||
fn visit_assign_expr(&mut self, e: &AssignExpr) {
|
||||
@ -387,29 +386,30 @@ impl Visit for FieldInitFinter {
|
||||
fn visit_call_expr(&mut self, e: &CallExpr) {
|
||||
match &e.callee {
|
||||
Callee::Super(_) | Callee::Import(_) => {}
|
||||
Callee::Expr(callee) => match &**callee {
|
||||
Expr::Member(callee) => match &*callee.obj {
|
||||
Expr::Ident(Ident {
|
||||
Callee::Expr(callee) => {
|
||||
if let Expr::Member(callee) = &**callee {
|
||||
if let Expr::Ident(Ident {
|
||||
sym: js_word!("Object"),
|
||||
..
|
||||
}) => match &callee.prop {
|
||||
MemberProp::Ident(Ident { sym: prop_sym, .. })
|
||||
if *prop_sym == *"assign" =>
|
||||
{
|
||||
let old = self.in_object_assign;
|
||||
self.in_object_assign = true;
|
||||
}) = &*callee.obj
|
||||
{
|
||||
match &callee.prop {
|
||||
MemberProp::Ident(Ident { sym: prop_sym, .. })
|
||||
if *prop_sym == *"assign" =>
|
||||
{
|
||||
let old = self.in_object_assign;
|
||||
self.in_object_assign = true;
|
||||
|
||||
e.args.visit_with(self);
|
||||
self.in_object_assign = old;
|
||||
e.args.visit_with(self);
|
||||
self.in_object_assign = old;
|
||||
|
||||
return;
|
||||
return;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
e.visit_children_with(self);
|
||||
@ -423,14 +423,13 @@ impl Visit for FieldInitFinter {
|
||||
}
|
||||
|
||||
if !self.in_rhs || self.in_object_assign {
|
||||
match &*e.obj {
|
||||
Expr::Ident(obj) => match &e.prop {
|
||||
if let Expr::Ident(obj) = &*e.obj {
|
||||
match &e.prop {
|
||||
MemberProp::Ident(Ident { sym: prop_sym, .. }) if *prop_sym == *"prototype" => {
|
||||
self.accessed.insert(obj.into());
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -680,7 +679,7 @@ fn calc_deps(new: &[ModuleItem]) -> StmtDepGraph {
|
||||
|
||||
{
|
||||
// Find extra initializations.
|
||||
let mut v = FieldInitFinter::default();
|
||||
let mut v = FieldInitFinder::default();
|
||||
item.visit_with(&mut v);
|
||||
|
||||
for id in v.accessed {
|
||||
@ -775,9 +774,9 @@ fn calc_deps(new: &[ModuleItem]) -> StmtDepGraph {
|
||||
// idx, idx_decl, declarator_index, &id
|
||||
// );
|
||||
if cfg!(debug_assertions) {
|
||||
let deps: Vec<_> =
|
||||
graph.neighbors_directed(idx, Dependencies).collect();
|
||||
assert!(deps.contains(&declarator_index));
|
||||
assert!(graph
|
||||
.neighbors_directed(idx, Dependencies)
|
||||
.any(|x| x == declarator_index));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -50,11 +50,8 @@ pub(crate) trait ExprExt: Into<Expr> {
|
||||
let lhs = lhs.into_id();
|
||||
|
||||
if cfg!(debug_assertions) {
|
||||
match &init {
|
||||
Expr::Ident(rhs) => {
|
||||
debug_assert_ne!(lhs, rhs.to_id());
|
||||
}
|
||||
_ => {}
|
||||
if let Expr::Ident(rhs) = &init {
|
||||
debug_assert_ne!(lhs, rhs.to_id());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -207,7 +207,7 @@ impl NodeResolver {
|
||||
/// Resolve a path as a directory, using the "main" key from a
|
||||
/// package.json file if it exists, or resolving to the
|
||||
/// index.EXT file if it exists.
|
||||
fn resolve_as_directory(&self, path: &PathBuf) -> Result<PathBuf, Error> {
|
||||
fn resolve_as_directory(&self, path: &Path) -> Result<PathBuf, Error> {
|
||||
// 1. If X/package.json is a file, use it.
|
||||
let pkg_path = path.join("package.json");
|
||||
if pkg_path.is_file() {
|
||||
@ -222,12 +222,12 @@ impl NodeResolver {
|
||||
}
|
||||
|
||||
/// Resolve using the package.json "main" key.
|
||||
fn resolve_package_main(&self, _: &PathBuf) -> Result<PathBuf, Error> {
|
||||
fn resolve_package_main(&self, _: &Path) -> Result<PathBuf, Error> {
|
||||
bail!("package.json is not supported")
|
||||
}
|
||||
|
||||
/// Resolve a directory to its index.EXT.
|
||||
fn resolve_index(&self, path: &PathBuf) -> Result<PathBuf, Error> {
|
||||
fn resolve_index(&self, path: &Path) -> Result<PathBuf, Error> {
|
||||
// 1. If X/index.js is a file, load X/index.js as JavaScript text.
|
||||
// 2. If X/index.json is a file, parse X/index.json to a JavaScript object.
|
||||
// 3. If X/index.node is a file, load X/index.node as binary addon.
|
||||
@ -263,9 +263,8 @@ impl NodeResolver {
|
||||
|
||||
impl Resolve for NodeResolver {
|
||||
fn resolve(&self, base: &FileName, target: &str) -> Result<FileName, Error> {
|
||||
match Url::parse(target) {
|
||||
Ok(v) => return Ok(FileName::Custom(v.to_string())),
|
||||
Err(_) => {}
|
||||
if let Ok(v) = Url::parse(target) {
|
||||
return Ok(FileName::Custom(v.to_string()));
|
||||
}
|
||||
|
||||
let base = match base {
|
||||
|
@ -1,5 +1,4 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use structopt::StructOpt;
|
||||
|
||||
/// Transform, compile files.
|
||||
|
@ -492,11 +492,11 @@ impl SingleThreadedComments {
|
||||
}
|
||||
|
||||
/// Borrows all the comments as (leading, trailing).
|
||||
pub fn borrow_all<'a>(
|
||||
&'a self,
|
||||
pub fn borrow_all(
|
||||
&self,
|
||||
) -> (
|
||||
Ref<'a, SingleThreadedCommentsMapInner>,
|
||||
Ref<'a, SingleThreadedCommentsMapInner>,
|
||||
Ref<SingleThreadedCommentsMapInner>,
|
||||
Ref<SingleThreadedCommentsMapInner>,
|
||||
) {
|
||||
(self.leading.borrow(), self.trailing.borrow())
|
||||
}
|
||||
|
@ -932,7 +932,7 @@ impl EmitterWriter {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::cognitive_complexity)]
|
||||
#[allow(clippy::cognitive_complexity, clippy::comparison_chain)]
|
||||
fn emit_message_default(
|
||||
&mut self,
|
||||
msp: &MultiSpan,
|
||||
|
@ -842,10 +842,7 @@ impl Level {
|
||||
}
|
||||
|
||||
pub fn is_failure_note(self) -> bool {
|
||||
match self {
|
||||
FailureNote => true,
|
||||
_ => false,
|
||||
}
|
||||
matches!(self, FailureNote)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,21 +119,17 @@ pub struct Annotation {
|
||||
impl Annotation {
|
||||
/// Whether this annotation is a vertical line placeholder.
|
||||
pub fn is_line(&self) -> bool {
|
||||
if let AnnotationType::MultilineLine(_) = self.annotation_type {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
matches!(self.annotation_type, AnnotationType::MultilineLine(_))
|
||||
}
|
||||
|
||||
pub fn is_multiline(&self) -> bool {
|
||||
match self.annotation_type {
|
||||
matches!(
|
||||
self.annotation_type,
|
||||
AnnotationType::Multiline(_)
|
||||
| AnnotationType::MultilineStart(_)
|
||||
| AnnotationType::MultilineLine(_)
|
||||
| AnnotationType::MultilineEnd(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
| AnnotationType::MultilineStart(_)
|
||||
| AnnotationType::MultilineLine(_)
|
||||
| AnnotationType::MultilineEnd(_)
|
||||
)
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
@ -165,10 +161,10 @@ impl Annotation {
|
||||
|
||||
pub fn takes_space(&self) -> bool {
|
||||
// Multiline annotations always have to keep vertical space.
|
||||
match self.annotation_type {
|
||||
AnnotationType::MultilineStart(_) | AnnotationType::MultilineEnd(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
matches!(
|
||||
self.annotation_type,
|
||||
AnnotationType::MultilineStart(_) | AnnotationType::MultilineEnd(_)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -178,6 +174,7 @@ pub struct StyledString {
|
||||
pub style: Style,
|
||||
}
|
||||
|
||||
#[allow(clippy::enum_variant_names)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Hash)]
|
||||
#[cfg_attr(
|
||||
feature = "diagnostic-serde",
|
||||
|
@ -30,6 +30,7 @@ impl Serialized {
|
||||
Serialized { field: vec }
|
||||
}
|
||||
|
||||
#[allow(clippy::should_implement_trait)]
|
||||
pub fn as_ref(&self) -> &rkyv::AlignedVec {
|
||||
&self.field
|
||||
}
|
||||
|
@ -709,7 +709,7 @@ impl SourceMap {
|
||||
whitespace_found = true;
|
||||
}
|
||||
|
||||
!(whitespace_found && !c.is_whitespace())
|
||||
!whitespace_found || c.is_whitespace()
|
||||
})
|
||||
}
|
||||
|
||||
@ -1256,10 +1256,10 @@ pub trait SourceMapGenConfig {
|
||||
|
||||
/// You can override this to control `sourceContents`.
|
||||
fn inline_sources_content(&self, f: &FileName) -> bool {
|
||||
match f {
|
||||
FileName::Real(..) | FileName::Custom(..) | FileName::Url(..) => false,
|
||||
_ => true,
|
||||
}
|
||||
!matches!(
|
||||
f,
|
||||
FileName::Real(..) | FileName::Custom(..) | FileName::Url(..)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -285,6 +285,7 @@ impl<T> RwLock<T> {
|
||||
self.0.try_borrow_mut().map_err(|_| ())
|
||||
}
|
||||
|
||||
#[allow(clippy::result_unit_err)]
|
||||
#[cfg(feature = "concurrent")]
|
||||
#[inline(always)]
|
||||
pub fn try_write(&self) -> Result<WriteGuard<'_, T>, ()> {
|
||||
|
@ -183,7 +183,7 @@ impl FileName {
|
||||
/// and would be rendered with `^^^`.
|
||||
/// - they can have a *label*. In this case, the label is written next to the
|
||||
/// mark in the snippet when we render.
|
||||
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, Default, Hash, PartialEq, Eq)]
|
||||
#[cfg_attr(
|
||||
feature = "diagnostic-serde",
|
||||
derive(serde::Serialize, serde::Deserialize)
|
||||
@ -441,10 +441,7 @@ impl Default for Span {
|
||||
impl MultiSpan {
|
||||
#[inline]
|
||||
pub fn new() -> MultiSpan {
|
||||
MultiSpan {
|
||||
primary_spans: vec![],
|
||||
span_labels: vec![],
|
||||
}
|
||||
Self::default()
|
||||
}
|
||||
|
||||
pub fn from_span(primary_span: Span) -> MultiSpan {
|
||||
|
@ -283,6 +283,7 @@ fn analyze_source_file_generic(
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[allow(clippy::identity_op)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
|
@ -742,11 +742,8 @@ where
|
||||
fn emit_complex_selector(&mut self, n: &ComplexSelector) -> Result {
|
||||
let mut need_space = false;
|
||||
for (idx, node) in n.children.iter().enumerate() {
|
||||
match node {
|
||||
ComplexSelectorChildren::Combinator(..) => {
|
||||
need_space = false;
|
||||
}
|
||||
_ => {}
|
||||
if let ComplexSelectorChildren::Combinator(..) = node {
|
||||
need_space = false;
|
||||
}
|
||||
|
||||
if idx != 0 && need_space {
|
||||
@ -755,11 +752,8 @@ where
|
||||
self.wr.write_space()?;
|
||||
}
|
||||
|
||||
match node {
|
||||
ComplexSelectorChildren::CompoundSelector(..) => {
|
||||
need_space = true;
|
||||
}
|
||||
_ => {}
|
||||
if let ComplexSelectorChildren::CompoundSelector(..) = node {
|
||||
need_space = true;
|
||||
}
|
||||
|
||||
emit!(self, node)
|
||||
@ -946,11 +940,8 @@ where
|
||||
if idx != 0 {
|
||||
self.write_delim(format)?;
|
||||
|
||||
match format & ListFormat::LinesMask {
|
||||
ListFormat::MultiLine => {
|
||||
self.wr.write_newline()?;
|
||||
}
|
||||
_ => {}
|
||||
if format & ListFormat::LinesMask == ListFormat::MultiLine {
|
||||
self.wr.write_newline()?;
|
||||
}
|
||||
}
|
||||
emit!(self, node)
|
||||
|
@ -14,13 +14,10 @@ struct Minifier {}
|
||||
impl VisitMut for Minifier {
|
||||
fn visit_mut_tokens(&mut self, tokens: &mut Tokens) {
|
||||
for tok in tokens.tokens.iter_mut() {
|
||||
match &mut tok.token {
|
||||
Token::WhiteSpace { value, .. } => {
|
||||
if value.len() >= 2 {
|
||||
*value = " ".into()
|
||||
}
|
||||
if let Token::WhiteSpace { value, .. } = &mut tok.token {
|
||||
if value.len() >= 2 {
|
||||
*value = " ".into()
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -143,15 +143,13 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(Token::WhiteSpace {
|
||||
Ok(Token::WhiteSpace {
|
||||
value: value.into(),
|
||||
});
|
||||
})
|
||||
}
|
||||
// U+0022 QUOTATION MARK (")
|
||||
// Consume a string token and return it.
|
||||
Some('"') => {
|
||||
return self.read_str(None);
|
||||
}
|
||||
Some('"') => self.read_str(None),
|
||||
// U+0023 NUMBER SIGN (#)
|
||||
Some('#') => {
|
||||
let first = self.next();
|
||||
@ -204,23 +202,17 @@ where
|
||||
return Ok(hash_token);
|
||||
}
|
||||
|
||||
return Ok(Token::Delim { value: '#' });
|
||||
Ok(Token::Delim { value: '#' })
|
||||
}
|
||||
// U+0027 APOSTROPHE (')
|
||||
// Consume a string token and return it.
|
||||
Some('\'') => {
|
||||
return self.read_str(None);
|
||||
}
|
||||
Some('\'') => self.read_str(None),
|
||||
// U+0028 LEFT PARENTHESIS (()
|
||||
// Return a <(-token>.
|
||||
Some('(') => {
|
||||
return Ok(tok!("("));
|
||||
}
|
||||
Some('(') => Ok(tok!("(")),
|
||||
// U+0029 RIGHT PARENTHESIS ())
|
||||
// Return a <)-token>.
|
||||
Some(')') => {
|
||||
return Ok(tok!(")"));
|
||||
}
|
||||
Some(')') => Ok(tok!(")")),
|
||||
// U+002B PLUS SIGN (+)
|
||||
Some('+') => {
|
||||
// If the input stream starts with a number, reconsume the current input code
|
||||
@ -233,13 +225,11 @@ where
|
||||
|
||||
// Otherwise, return a <delim-token> with its value set to the current input
|
||||
// code point.
|
||||
return Ok(Token::Delim { value: '+' });
|
||||
Ok(Token::Delim { value: '+' })
|
||||
}
|
||||
// U+002C COMMA (,)
|
||||
// Return a <comma-token>.
|
||||
Some(',') => {
|
||||
return Ok(tok!(","));
|
||||
}
|
||||
Some(',') => Ok(tok!(",")),
|
||||
// U+002D HYPHEN-MINUS (-)
|
||||
Some('-') => {
|
||||
// If the input stream starts with a number, reconsume the current input code
|
||||
@ -267,7 +257,7 @@ where
|
||||
|
||||
// Otherwise, return a <delim-token> with its value set to the current input
|
||||
// code point.
|
||||
return Ok(Token::Delim { value: '-' });
|
||||
Ok(Token::Delim { value: '-' })
|
||||
}
|
||||
// U+002E FULL STOP (.)
|
||||
Some('.') => {
|
||||
@ -281,18 +271,14 @@ where
|
||||
|
||||
// Otherwise, return a <delim-token> with its value set to the current input
|
||||
// code point.
|
||||
return Ok(Token::Delim { value: '.' });
|
||||
Ok(Token::Delim { value: '.' })
|
||||
}
|
||||
// U+003A COLON (:)
|
||||
// Return a <colon-token>.
|
||||
Some(':') => {
|
||||
return Ok(tok!(":"));
|
||||
}
|
||||
Some(':') => Ok(tok!(":")),
|
||||
// U+003B SEMICOLON (;)
|
||||
// Return a <semicolon-token>.
|
||||
Some(';') => {
|
||||
return Ok(tok!(";"));
|
||||
}
|
||||
Some(';') => Ok(tok!(";")),
|
||||
// U+003C LESS-THAN SIGN (<)
|
||||
Some('<') => {
|
||||
// If the next 3 input code points are U+0021 EXCLAMATION MARK U+002D
|
||||
@ -311,7 +297,7 @@ where
|
||||
|
||||
// Otherwise, return a <delim-token> with its value set to the current input
|
||||
// code point.
|
||||
return Ok(Token::Delim { value: '<' });
|
||||
Ok(Token::Delim { value: '<' })
|
||||
}
|
||||
// U+0040 COMMERCIAL AT (@)
|
||||
Some('@') => {
|
||||
@ -333,13 +319,11 @@ where
|
||||
|
||||
// Otherwise, return a <delim-token> with its value set to the current input
|
||||
// code point.
|
||||
return Ok(Token::Delim { value: '@' });
|
||||
Ok(Token::Delim { value: '@' })
|
||||
}
|
||||
// U+005B LEFT SQUARE BRACKET ([)
|
||||
// Return a <[-token>.
|
||||
Some('[') => {
|
||||
return Ok(tok!("["));
|
||||
}
|
||||
Some('[') => Ok(tok!("[")),
|
||||
// U+005C REVERSE SOLIDUS (\)
|
||||
Some('\\') => {
|
||||
// If the input stream starts with a valid escape, reconsume the current input
|
||||
@ -352,48 +336,40 @@ where
|
||||
|
||||
// Otherwise, this is a parse error. Return a <delim-token> with its value set
|
||||
// to the current input code point.
|
||||
return Ok(Token::Delim { value: '\\' });
|
||||
Ok(Token::Delim { value: '\\' })
|
||||
}
|
||||
// U+005D RIGHT SQUARE BRACKET (])
|
||||
// Return a <]-token>.
|
||||
Some(']') => {
|
||||
return Ok(tok!("]"));
|
||||
}
|
||||
Some(']') => Ok(tok!("]")),
|
||||
// U+007B LEFT CURLY BRACKET ({)
|
||||
// Return a <{-token>.
|
||||
Some('{') => {
|
||||
return Ok(tok!("{"));
|
||||
}
|
||||
Some('{') => Ok(tok!("{")),
|
||||
// U+007D RIGHT CURLY BRACKET (})
|
||||
// Return a <}-token>.
|
||||
Some('}') => {
|
||||
return Ok(tok!("}"));
|
||||
}
|
||||
Some('}') => Ok(tok!("}")),
|
||||
// digit
|
||||
// Reconsume the current input code point, consume a numeric token, and return it.
|
||||
Some('0'..='9') => {
|
||||
self.reconsume();
|
||||
|
||||
return self.read_numeric();
|
||||
self.read_numeric()
|
||||
}
|
||||
// name-start code point
|
||||
// Reconsume the current input code point, consume an ident-like token, and return it.
|
||||
Some(c) if is_name_start(c) => {
|
||||
self.reconsume();
|
||||
|
||||
return self.read_ident_like();
|
||||
self.read_ident_like()
|
||||
}
|
||||
// EOF
|
||||
// Return an <EOF-token>.
|
||||
None => {
|
||||
// TODO: Return an <EOF-token>.
|
||||
return Err(ErrorKind::Eof);
|
||||
Err(ErrorKind::Eof)
|
||||
}
|
||||
// anything else
|
||||
// Return a <delim-token> with its value set to the current input code point.
|
||||
Some(c) => {
|
||||
return Ok(Token::Delim { value: c });
|
||||
}
|
||||
Some(c) => Ok(Token::Delim { value: c }),
|
||||
}
|
||||
}
|
||||
|
||||
@ -735,7 +711,7 @@ where
|
||||
|
||||
raw.push(c);
|
||||
// TODO: fix me
|
||||
raw.push_str(&self.input.slice(start_pos, end_pos));
|
||||
raw.push_str(self.input.slice(start_pos, end_pos));
|
||||
|
||||
// if the next input code point is U+0029 RIGHT PARENTHESIS ()) or EOF, consume
|
||||
// it and return the <url-token> (if EOF was encountered, this is a parse
|
||||
@ -876,26 +852,26 @@ where
|
||||
// is for a surrogate, or is greater than the maximum allowed code point, return
|
||||
// U+FFFD REPLACEMENT CHARACTER (<28>).
|
||||
// TODO: fix me
|
||||
let hex = char::from_u32(hex).ok_or_else(|| ErrorKind::InvalidEscape)?;
|
||||
let hex = char::from_u32(hex).ok_or(ErrorKind::InvalidEscape)?;
|
||||
|
||||
// Otherwise, return the code point with that value.
|
||||
return Ok((hex, raw));
|
||||
Ok((hex, raw))
|
||||
}
|
||||
// EOF
|
||||
// This is a parse error. Return U+FFFD REPLACEMENT CHARACTER (<28>).
|
||||
None => {
|
||||
let value = '\u{FFFD}';
|
||||
|
||||
raw.push(value.clone());
|
||||
raw.push(value);
|
||||
|
||||
return Ok((value, raw));
|
||||
Ok((value, raw))
|
||||
}
|
||||
// anything else
|
||||
// Return the current input code point.
|
||||
Some(c) => {
|
||||
raw.push(c);
|
||||
|
||||
return Ok((c, raw));
|
||||
Ok((c, raw))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -947,39 +923,33 @@ where
|
||||
match second {
|
||||
// If the second code point is a name-start code point
|
||||
// return true.
|
||||
Some(c) if is_name_start(c) => return Ok(true),
|
||||
Some(c) if is_name_start(c) => Ok(true),
|
||||
// or a U+002D HYPHEN-MINUS,
|
||||
// return true.
|
||||
Some('-') => return Ok(true),
|
||||
Some('-') => Ok(true),
|
||||
// or the second and third code points are a valid escape
|
||||
// return true.
|
||||
Some(_) => {
|
||||
let third = maybe_third.or_else(|| self.next_next());
|
||||
|
||||
return self.is_valid_escape(second, third);
|
||||
self.is_valid_escape(second, third)
|
||||
}
|
||||
// Otherwise, return false.
|
||||
_ => {
|
||||
return Ok(false);
|
||||
}
|
||||
_ => Ok(false),
|
||||
}
|
||||
}
|
||||
// name-start code point
|
||||
// Return true.
|
||||
Some(c) if is_name_start(c) => {
|
||||
return Ok(true);
|
||||
}
|
||||
Some(c) if is_name_start(c) => Ok(true),
|
||||
// U+005C REVERSE SOLIDUS (\)
|
||||
// If the first and second code points are a valid escape, return true. Otherwise,
|
||||
// return false.
|
||||
Some('\\') => {
|
||||
let second = maybe_second.or_else(|| self.next());
|
||||
|
||||
return Ok(self.is_valid_escape(first, second)?);
|
||||
}
|
||||
_ => {
|
||||
return Ok(false);
|
||||
Ok(self.is_valid_escape(first, second)?)
|
||||
}
|
||||
_ => Ok(false),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -249,10 +249,10 @@ where
|
||||
|
||||
eat!(self, ";");
|
||||
|
||||
return Ok(CharsetRule {
|
||||
Ok(CharsetRule {
|
||||
span: span!(self, span.lo),
|
||||
charset,
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -285,11 +285,11 @@ where
|
||||
|
||||
eat!(self, ";");
|
||||
|
||||
return Ok(ImportRule {
|
||||
Ok(ImportRule {
|
||||
span: span!(self, span.lo),
|
||||
src: src.unwrap(),
|
||||
condition,
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -329,11 +329,11 @@ where
|
||||
expect!(self, "}");
|
||||
}
|
||||
|
||||
return Ok(KeyframesRule {
|
||||
Ok(KeyframesRule {
|
||||
span: span!(self, span.lo),
|
||||
name,
|
||||
blocks,
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -345,10 +345,10 @@ where
|
||||
let span = self.input.cur_span()?;
|
||||
let block = self.parse()?;
|
||||
|
||||
return Ok(ViewportRule {
|
||||
Ok(ViewportRule {
|
||||
span: span!(self, span.lo),
|
||||
block,
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -393,11 +393,11 @@ where
|
||||
|
||||
eat!(self, ";");
|
||||
|
||||
return Ok(NamespaceRule {
|
||||
Ok(NamespaceRule {
|
||||
span: span!(self, span.lo),
|
||||
prefix,
|
||||
uri,
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -409,10 +409,10 @@ where
|
||||
let span = self.input.cur_span()?;
|
||||
let block = self.parse()?;
|
||||
|
||||
return Ok(FontFaceRule {
|
||||
Ok(FontFaceRule {
|
||||
span: span!(self, span.lo),
|
||||
block,
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -432,11 +432,11 @@ where
|
||||
|
||||
expect!(self, "}");
|
||||
|
||||
return Ok(SupportsRule {
|
||||
Ok(SupportsRule {
|
||||
span: span!(self, span.lo),
|
||||
query,
|
||||
rules,
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -641,11 +641,11 @@ where
|
||||
|
||||
expect!(self, "}");
|
||||
|
||||
return Ok(MediaRule {
|
||||
Ok(MediaRule {
|
||||
span: span!(self, span.lo),
|
||||
query,
|
||||
rules,
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -759,7 +759,7 @@ where
|
||||
}));
|
||||
}
|
||||
|
||||
return Ok(base);
|
||||
Ok(base)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -384,7 +384,7 @@ where
|
||||
raw: str.1,
|
||||
}))
|
||||
}
|
||||
_ => Err(Error::new(span, ErrorKind::InvalidAttrSelectorMatcherValue))?,
|
||||
_ => return Err(Error::new(span, ErrorKind::InvalidAttrSelectorMatcherValue)),
|
||||
};
|
||||
|
||||
self.input.skip_ws()?;
|
||||
@ -398,7 +398,7 @@ where
|
||||
|
||||
bump!(self);
|
||||
}
|
||||
_ => Err(Error::new(span, ErrorKind::InvalidAttrSelectorModifier))?,
|
||||
_ => return Err(Error::new(span, ErrorKind::InvalidAttrSelectorModifier)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -520,7 +520,7 @@ where
|
||||
a = Some(if has_minus_sign { -1 } else {1 });
|
||||
a_raw = Some((if has_plus_sign { "+" } else if has_minus_sign { "-" } else { "" }).into());
|
||||
|
||||
n_value = if has_minus_sign { ident_value.clone()[1..].to_string() } else { ident_value.clone().to_string() };
|
||||
n_value = if has_minus_sign { ident_value[1..].to_string() } else { ident_value.to_string() };
|
||||
}
|
||||
Token::Dimension { .. } => {
|
||||
let dimension = match bump!(self) {
|
||||
|
@ -106,6 +106,7 @@ impl BinaryOp {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::enum_variant_names)]
|
||||
#[derive(StringEnum, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash, EqIgnoreSpan)]
|
||||
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||
#[cfg_attr(
|
||||
|
@ -111,6 +111,7 @@ pub enum TsEntityName {
|
||||
// TypeScript type members (for type literal / interface / class)
|
||||
// ================
|
||||
|
||||
#[allow(clippy::enum_variant_names)]
|
||||
#[ast_node]
|
||||
#[derive(Eq, Hash, Is, EqIgnoreSpan)]
|
||||
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||
@ -238,6 +239,7 @@ pub struct TsIndexSignature {
|
||||
// TypeScript types
|
||||
// ================
|
||||
|
||||
#[allow(clippy::enum_variant_names)]
|
||||
#[ast_node]
|
||||
#[derive(Eq, Hash, Is, EqIgnoreSpan)]
|
||||
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||
@ -347,6 +349,7 @@ pub struct TsKeywordType {
|
||||
pub kind: TsKeywordTypeKind,
|
||||
}
|
||||
|
||||
#[allow(clippy::enum_variant_names)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, EqIgnoreSpan)]
|
||||
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
|
||||
#[cfg_attr(
|
||||
|
@ -189,17 +189,17 @@ impl EndsWithAlphaNum for VarDecl {
|
||||
|
||||
impl EndsWithAlphaNum for Expr {
|
||||
fn ends_with_alpha_num(&self) -> bool {
|
||||
match self {
|
||||
!matches!(
|
||||
self,
|
||||
Expr::Array(..)
|
||||
| Expr::Object(..)
|
||||
| Expr::Lit(Lit::Str(..))
|
||||
| Expr::Paren(..)
|
||||
| Expr::Member(MemberExpr {
|
||||
prop: MemberProp::Computed(..),
|
||||
..
|
||||
}) => false,
|
||||
_ => true,
|
||||
}
|
||||
| Expr::Object(..)
|
||||
| Expr::Lit(Lit::Str(..))
|
||||
| Expr::Paren(..)
|
||||
| Expr::Member(MemberExpr {
|
||||
prop: MemberProp::Computed(..),
|
||||
..
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -359,7 +359,6 @@ mod tests {
|
||||
tsx: file_name.contains("tsx"),
|
||||
decorators: true,
|
||||
no_early_errors: true,
|
||||
..Default::default()
|
||||
}),
|
||||
EsVersion::Es2015,
|
||||
(&*fm).into(),
|
||||
|
@ -56,12 +56,8 @@ impl Visit for ConstAssign {
|
||||
fn visit_pat(&mut self, p: &Pat) {
|
||||
p.visit_children_with(self);
|
||||
|
||||
match p {
|
||||
Pat::Ident(p) => {
|
||||
self.check(&p.id);
|
||||
}
|
||||
|
||||
_ => {}
|
||||
if let Pat::Ident(p) = p {
|
||||
self.check(&p.id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,14 +105,10 @@ impl Visit for DuplicateBindings {
|
||||
fn visit_pat(&mut self, p: &Pat) {
|
||||
p.visit_children_with(self);
|
||||
|
||||
match p {
|
||||
Pat::Ident(p) => {
|
||||
if self.is_pat_decl {
|
||||
self.add(&p.id, true);
|
||||
}
|
||||
if let Pat::Ident(p) = p {
|
||||
if self.is_pat_decl {
|
||||
self.add(&p.id, true);
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ struct BrowserCache {
|
||||
|
||||
/// Helper to find the nearest `package.json` file to get
|
||||
/// the base directory for a package.
|
||||
fn find_package_root(path: &PathBuf) -> Option<PathBuf> {
|
||||
fn find_package_root(path: &Path) -> Option<PathBuf> {
|
||||
let mut parent = path.parent();
|
||||
while let Some(p) = parent {
|
||||
let pkg = p.join(PACKAGE);
|
||||
@ -164,7 +164,7 @@ impl NodeModulesResolver {
|
||||
|
||||
/// Resolve a path as a directory, using the "main" key from a package.json
|
||||
/// file if it exists, or resolving to the index.EXT file if it exists.
|
||||
fn resolve_as_directory(&self, path: &PathBuf) -> Result<Option<PathBuf>, Error> {
|
||||
fn resolve_as_directory(&self, path: &Path) -> Result<Option<PathBuf>, Error> {
|
||||
let pkg_path = path.join(PACKAGE);
|
||||
if pkg_path.is_file() {
|
||||
if let Some(main) = self.resolve_package_entry(path, &pkg_path)? {
|
||||
@ -185,8 +185,8 @@ impl NodeModulesResolver {
|
||||
/// Resolve using the package.json "main" or "browser" keys.
|
||||
fn resolve_package_entry(
|
||||
&self,
|
||||
pkg_dir: &PathBuf,
|
||||
pkg_path: &PathBuf,
|
||||
pkg_dir: &Path,
|
||||
pkg_path: &Path,
|
||||
) -> Result<Option<PathBuf>, Error> {
|
||||
let file = File::open(pkg_path)?;
|
||||
let reader = BufReader::new(file);
|
||||
|
@ -102,18 +102,15 @@ where
|
||||
.context("not processed by tsc resolver because it's relative import");
|
||||
}
|
||||
|
||||
match base {
|
||||
FileName::Real(v) => {
|
||||
if v.components().any(|c| match c {
|
||||
Component::Normal(v) => v == "node_modules",
|
||||
_ => false,
|
||||
}) {
|
||||
return self.inner.resolve(base, src).context(
|
||||
"not processed by tsc resolver because base module is in node_modules",
|
||||
);
|
||||
}
|
||||
if let FileName::Real(v) = base {
|
||||
if v.components().any(|c| match c {
|
||||
Component::Normal(v) => v == "node_modules",
|
||||
_ => false,
|
||||
}) {
|
||||
return self.inner.resolve(base, src).context(
|
||||
"not processed by tsc resolver because base module is in node_modules",
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping
|
||||
|
@ -695,9 +695,8 @@ where
|
||||
fn visit_pat(&mut self, n: &Pat) {
|
||||
n.visit_children_with(self);
|
||||
|
||||
match n {
|
||||
Pat::Ident(i) => self.visit_pat_id(&i.id),
|
||||
_ => {}
|
||||
if let Pat::Ident(i) = n {
|
||||
self.visit_pat_id(&i.id)
|
||||
}
|
||||
}
|
||||
|
||||
@ -708,11 +707,8 @@ where
|
||||
};
|
||||
n.visit_children_with(&mut *self.with_ctx(ctx));
|
||||
|
||||
match n {
|
||||
Prop::Shorthand(i) => {
|
||||
self.report_usage(i, false);
|
||||
}
|
||||
_ => {}
|
||||
if let Prop::Shorthand(i) = n {
|
||||
self.report_usage(i, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,7 +158,7 @@ impl<'a, I: Input> Lexer<'a, I> {
|
||||
if ch == '\\' {
|
||||
has_escape = true;
|
||||
out.push_str(self.input.slice(chunk_start, cur_pos));
|
||||
out.push_str("\\");
|
||||
out.push('\\');
|
||||
self.bump();
|
||||
|
||||
chunk_start = self.input.cur_pos();
|
||||
|
@ -62,7 +62,7 @@ impl IntoIterator for Char {
|
||||
let c = unsafe { char::from_u32_unchecked(self.0) };
|
||||
let escaped = c.escape_unicode().to_string();
|
||||
|
||||
debug_assert!(escaped.starts_with("\\"));
|
||||
debug_assert!(escaped.starts_with('\\'));
|
||||
|
||||
let mut buf = smallvec![];
|
||||
buf.push('\\');
|
||||
@ -149,9 +149,8 @@ impl<'a, I: Input> Lexer<'a, I> {
|
||||
let b = self.buf.clone();
|
||||
let mut buf = b.borrow_mut();
|
||||
buf.clear();
|
||||
let res = op(self, &mut buf);
|
||||
|
||||
res
|
||||
op(self, &mut buf)
|
||||
}
|
||||
|
||||
/// babel: `getTokenFromCode`
|
||||
@ -180,7 +179,7 @@ impl<'a, I: Input> Lexer<'a, I> {
|
||||
return Ok(Some(tok!('.')));
|
||||
}
|
||||
};
|
||||
if '0' <= next && next <= '9' {
|
||||
if ('0'..='9').contains(&next) {
|
||||
return self
|
||||
.read_number(true)
|
||||
.map(|v| match v {
|
||||
@ -447,7 +446,7 @@ impl<'a, I: Input> Lexer<'a, I> {
|
||||
}
|
||||
|
||||
self.input.bump(); // '#'
|
||||
return Ok(Some(Token::Hash));
|
||||
Ok(Some(Token::Hash))
|
||||
}
|
||||
|
||||
fn read_token_interpreter(&mut self) -> LexResult<bool> {
|
||||
@ -788,7 +787,7 @@ impl<'a, I: Input> Lexer<'a, I> {
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
let value = convert(&buf);
|
||||
let value = convert(buf);
|
||||
|
||||
Ok((value, has_escape))
|
||||
})
|
||||
@ -886,10 +885,10 @@ impl<'a, I: Input> Lexer<'a, I> {
|
||||
}
|
||||
|
||||
l.emit_error(start, SyntaxError::UnterminatedStrLit);
|
||||
return Ok(Token::Str {
|
||||
Ok(Token::Str {
|
||||
value: (&**out).into(),
|
||||
has_escape,
|
||||
});
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -103,7 +103,7 @@ impl<'a, I: Input> Lexer<'a, I> {
|
||||
let dec_val = self.read_int(10, 0, &mut raw)?;
|
||||
val = {
|
||||
if let Some(..) = dec_val {
|
||||
raw_val.push_str(&raw.0.as_ref().unwrap());
|
||||
raw_val.push_str(raw.0.as_ref().unwrap());
|
||||
}
|
||||
|
||||
raw_val
|
||||
@ -419,7 +419,7 @@ impl<'a, I: Input> Lexer<'a, I> {
|
||||
}
|
||||
self.emit_strict_mode_error(start, SyntaxError::LegacyOctal);
|
||||
|
||||
return Ok(val);
|
||||
Ok(val)
|
||||
}
|
||||
}
|
||||
|
||||
@ -433,13 +433,13 @@ mod tests {
|
||||
where
|
||||
F: FnOnce(&mut Lexer<'_, StringInput<'_>>) -> Ret,
|
||||
{
|
||||
crate::with_test_sess(s, |_, fm| {
|
||||
crate::with_test_sess(s, |_, input| {
|
||||
let mut l = Lexer::new(
|
||||
Syntax::Es(EsConfig {
|
||||
..Default::default()
|
||||
}),
|
||||
Default::default(),
|
||||
fm.into(),
|
||||
input,
|
||||
None,
|
||||
);
|
||||
let ret = f(&mut l);
|
||||
|
@ -93,18 +93,17 @@ impl<'a> From<&'a Token> for TokenType {
|
||||
Token::Word(Word::Keyword(k)) => TokenType::Keyword(k),
|
||||
_ => TokenType::Other {
|
||||
before_expr: t.before_expr(),
|
||||
can_have_trailing_comment: match *t {
|
||||
can_have_trailing_comment: matches!(
|
||||
*t,
|
||||
Token::Num(..)
|
||||
| Token::Str { .. }
|
||||
| Token::Word(Word::Ident(..))
|
||||
| Token::DollarLBrace
|
||||
| Token::Regex(..)
|
||||
| Token::BigInt(..)
|
||||
| Token::JSXText { .. }
|
||||
| Token::RBrace => true,
|
||||
|
||||
_ => false,
|
||||
},
|
||||
| Token::Str { .. }
|
||||
| Token::Word(Word::Ident(..))
|
||||
| Token::DollarLBrace
|
||||
| Token::Regex(..)
|
||||
| Token::BigInt(..)
|
||||
| Token::JSXText { .. }
|
||||
| Token::RBrace
|
||||
),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -87,41 +87,36 @@ impl Fold for Entry {
|
||||
items.move_flat_map(|item| {
|
||||
let item: ModuleItem = item.fold_with(self);
|
||||
|
||||
match &item {
|
||||
ModuleItem::Stmt(Stmt::Expr(ExprStmt { expr, .. })) => match &**expr {
|
||||
Expr::Call(CallExpr {
|
||||
callee: Callee::Expr(callee),
|
||||
ref args,
|
||||
if let ModuleItem::Stmt(Stmt::Expr(ExprStmt { expr, .. })) = &item {
|
||||
if let Expr::Call(CallExpr {
|
||||
callee: Callee::Expr(callee),
|
||||
ref args,
|
||||
..
|
||||
}) = &**expr
|
||||
{
|
||||
if let Expr::Ident(Ident {
|
||||
sym: js_word!("require"),
|
||||
..
|
||||
}) => match &**callee {
|
||||
Expr::Ident(Ident {
|
||||
sym: js_word!("require"),
|
||||
..
|
||||
}) => {
|
||||
if args.len() == 1
|
||||
&& match &args[0] {
|
||||
ExprOrSpread { spread: None, expr } => match &**expr {
|
||||
Expr::Lit(Lit::Str(s)) => {
|
||||
s.value == *"core-js"
|
||||
|| s.value == *"@swc/polyfill"
|
||||
|| s.value == *"@babel/polyfill"
|
||||
}
|
||||
_ => false,
|
||||
},
|
||||
_ => false,
|
||||
}) = &**callee
|
||||
{
|
||||
if args.len() == 1
|
||||
&& if let ExprOrSpread { spread: None, expr } = &args[0] {
|
||||
if let Expr::Lit(Lit::Str(s)) = &**expr {
|
||||
s.value == *"core-js"
|
||||
|| s.value == *"@swc/polyfill"
|
||||
|| s.value == *"@babel/polyfill"
|
||||
} else {
|
||||
false
|
||||
}
|
||||
&& self.add_all("@swc/polyfill")
|
||||
{
|
||||
return None;
|
||||
} else {
|
||||
false
|
||||
}
|
||||
&& self.add_all("@swc/polyfill")
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
},
|
||||
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some(item)
|
||||
|
@ -60,17 +60,17 @@ impl UsageVisitor {
|
||||
..
|
||||
} = self;
|
||||
|
||||
self.required.extend(features.iter().filter_map(|f| {
|
||||
self.required.extend(features.iter().filter(|f| {
|
||||
if !*is_any_target {
|
||||
if let Some(v) = BUILTINS.get(&**f) {
|
||||
if let Some(v) = BUILTINS.get(&***f) {
|
||||
// Skip
|
||||
if !should_enable(*target, *v, true) {
|
||||
return None;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some(f)
|
||||
true
|
||||
}));
|
||||
}
|
||||
|
||||
@ -138,33 +138,21 @@ impl Visit for UsageVisitor {
|
||||
d.visit_children_with(self);
|
||||
|
||||
if let Some(ref init) = d.init {
|
||||
match d.name {
|
||||
// const { keys, values } = Object
|
||||
Pat::Object(ref o) => self.visit_object_pat_props(init, &o.props),
|
||||
_ => {}
|
||||
}
|
||||
} else {
|
||||
match d.name {
|
||||
// const { keys, values } = Object
|
||||
Pat::Object(ref o) => self.visit_object_pat_props(
|
||||
&Expr::Ident(Ident::new(js_word!(""), DUMMY_SP)),
|
||||
&o.props,
|
||||
),
|
||||
_ => {}
|
||||
if let Pat::Object(ref o) = d.name {
|
||||
self.visit_object_pat_props(init, &o.props)
|
||||
}
|
||||
} else if let Pat::Object(ref o) = d.name {
|
||||
self.visit_object_pat_props(&Expr::Ident(Ident::new(js_word!(""), DUMMY_SP)), &o.props)
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_assign_expr(&mut self, e: &AssignExpr) {
|
||||
e.visit_children_with(self);
|
||||
|
||||
match &e.left {
|
||||
// ({ keys, values } = Object)
|
||||
PatOrExpr::Pat(pat) => match &**pat {
|
||||
Pat::Object(ref o) => self.visit_object_pat_props(&e.right, &o.props),
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
if let PatOrExpr::Pat(pat) = &e.left {
|
||||
if let Pat::Object(ref o) = &**pat {
|
||||
self.visit_object_pat_props(&e.right, &o.props)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -259,35 +247,32 @@ impl Visit for UsageVisitor {
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
match &*node.obj {
|
||||
Expr::Ident(obj) => {
|
||||
for (ty, props) in STATIC_PROPERTIES {
|
||||
if obj.sym == **ty {
|
||||
match &node.prop {
|
||||
MemberProp::Computed(ComputedPropName { expr, .. }) => {
|
||||
if let Expr::Lit(Lit::Str(Str { value, .. })) = &**expr {
|
||||
for (name, imports) in INSTANCE_PROPERTIES {
|
||||
if *value == **name {
|
||||
self.add(imports);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MemberProp::Ident(ref p) => {
|
||||
for (prop, imports) in *props {
|
||||
if p.sym == **prop {
|
||||
if let Expr::Ident(obj) = &*node.obj {
|
||||
for (ty, props) in STATIC_PROPERTIES {
|
||||
if obj.sym == **ty {
|
||||
match &node.prop {
|
||||
MemberProp::Computed(ComputedPropName { expr, .. }) => {
|
||||
if let Expr::Lit(Lit::Str(Str { value, .. })) = &**expr {
|
||||
for (name, imports) in INSTANCE_PROPERTIES {
|
||||
if *value == **name {
|
||||
self.add(imports);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
|
||||
MemberProp::Ident(ref p) => {
|
||||
for (prop, imports) in *props {
|
||||
if p.sym == **prop {
|
||||
self.add(imports);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -304,13 +289,10 @@ impl Visit for UsageVisitor {
|
||||
e.visit_children_with(self);
|
||||
|
||||
if match &e.callee {
|
||||
Callee::Expr(callee) => match &**callee {
|
||||
Expr::Member(MemberExpr {
|
||||
Callee::Expr(callee) => matches!(&**callee, Expr::Member(MemberExpr {
|
||||
prop: MemberProp::Computed(ComputedPropName { expr, .. }),
|
||||
..
|
||||
}) if is_symbol_iterator(expr) => true,
|
||||
_ => false,
|
||||
},
|
||||
}) if is_symbol_iterator(expr)),
|
||||
_ => false,
|
||||
} {
|
||||
self.add(&["web.dom.iterable"])
|
||||
@ -351,13 +333,13 @@ fn is_symbol_iterator(e: &Expr) -> bool {
|
||||
..
|
||||
}),
|
||||
..
|
||||
}) => match &**obj {
|
||||
}) => matches!(
|
||||
&**obj,
|
||||
Expr::Ident(Ident {
|
||||
sym: js_word!("Symbol"),
|
||||
..
|
||||
}) => true,
|
||||
_ => false,
|
||||
},
|
||||
})
|
||||
),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -75,13 +75,13 @@ impl Entry {
|
||||
}
|
||||
|
||||
if let Some(features) = ENTRIES.get(src) {
|
||||
self.imports.extend(features.iter().filter_map(|f| {
|
||||
let feature = CORE_JS_COMPAT_DATA.get(&**f);
|
||||
self.imports.extend(features.iter().filter(|f| {
|
||||
let feature = CORE_JS_COMPAT_DATA.get(&***f);
|
||||
|
||||
if !*is_any_target {
|
||||
if let Some(feature) = feature {
|
||||
if !should_enable(*target, *feature, true) {
|
||||
return None;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -92,12 +92,12 @@ impl Entry {
|
||||
.iter()
|
||||
.filter(|(version, _features)| *corejs_version < **version)
|
||||
{
|
||||
if features.contains(&*f) {
|
||||
return None;
|
||||
if features.contains(*f) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Some(f)
|
||||
true
|
||||
}));
|
||||
|
||||
true
|
||||
|
@ -62,22 +62,22 @@ impl UsageVisitor {
|
||||
..
|
||||
} = self;
|
||||
|
||||
self.required.extend(features.iter().filter_map(|f| {
|
||||
self.required.extend(features.iter().filter(|f| {
|
||||
if !*shipped_proposals && f.starts_with("esnext.") {
|
||||
return None;
|
||||
return false;
|
||||
}
|
||||
|
||||
let feature = CORE_JS_COMPAT_DATA.get(&**f);
|
||||
let feature = CORE_JS_COMPAT_DATA.get(&***f);
|
||||
|
||||
if !*is_any_target {
|
||||
if let Some(feature) = feature {
|
||||
if !should_enable(*target, *feature, true) {
|
||||
return None;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some(f)
|
||||
true
|
||||
}));
|
||||
}
|
||||
|
||||
@ -151,28 +151,22 @@ impl Visit for UsageVisitor {
|
||||
fn visit_assign_expr(&mut self, e: &AssignExpr) {
|
||||
e.visit_children_with(self);
|
||||
|
||||
match &e.left {
|
||||
// ({ keys, values } = Object)
|
||||
PatOrExpr::Pat(pat) => match &**pat {
|
||||
Pat::Object(ref o) => self.visit_object_pat_props(&e.right, &o.props),
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
if let PatOrExpr::Pat(pat) = &e.left {
|
||||
if let Pat::Object(ref o) = &**pat {
|
||||
self.visit_object_pat_props(&e.right, &o.props)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_bin_expr(&mut self, e: &BinExpr) {
|
||||
e.visit_children_with(self);
|
||||
|
||||
match e.op {
|
||||
op!("in") => {
|
||||
// 'entries' in Object
|
||||
// 'entries' in [1, 2, 3]
|
||||
if let Expr::Lit(Lit::Str(str)) = &*e.left {
|
||||
self.add_property_deps(&e.right, &str.value);
|
||||
}
|
||||
if e.op == op!("in") {
|
||||
// 'entries' in Object
|
||||
// 'entries' in [1, 2, 3]
|
||||
if let Expr::Lit(Lit::Str(str)) = &*e.left {
|
||||
self.add_property_deps(&e.right, &str.value);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -188,9 +182,8 @@ impl Visit for UsageVisitor {
|
||||
fn visit_expr(&mut self, e: &Expr) {
|
||||
e.visit_children_with(self);
|
||||
|
||||
match e {
|
||||
Expr::Ident(i) => self.add_builtin(&i.sym),
|
||||
_ => {}
|
||||
if let Expr::Ident(i) = e {
|
||||
self.add_builtin(&i.sym)
|
||||
}
|
||||
}
|
||||
|
||||
@ -243,20 +236,11 @@ impl Visit for UsageVisitor {
|
||||
d.visit_children_with(self);
|
||||
|
||||
if let Some(ref init) = d.init {
|
||||
match d.name {
|
||||
// const { keys, values } = Object
|
||||
Pat::Object(ref o) => self.visit_object_pat_props(init, &o.props),
|
||||
_ => {}
|
||||
}
|
||||
} else {
|
||||
match d.name {
|
||||
// const { keys, values } = Object
|
||||
Pat::Object(ref o) => self.visit_object_pat_props(
|
||||
&Expr::Ident(Ident::new(js_word!(""), DUMMY_SP)),
|
||||
&o.props,
|
||||
),
|
||||
_ => {}
|
||||
if let Pat::Object(ref o) = d.name {
|
||||
self.visit_object_pat_props(init, &o.props)
|
||||
}
|
||||
} else if let Pat::Object(ref o) = d.name {
|
||||
self.visit_object_pat_props(&Expr::Ident(Ident::new(js_word!(""), DUMMY_SP)), &o.props)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -399,17 +399,18 @@ impl Fold for Polyfills {
|
||||
);
|
||||
}
|
||||
|
||||
m.body.retain(|item| match item {
|
||||
ModuleItem::ModuleDecl(ModuleDecl::Import(ImportDecl {
|
||||
src:
|
||||
Str {
|
||||
m.body.retain(|item| {
|
||||
!matches!(
|
||||
item,
|
||||
ModuleItem::ModuleDecl(ModuleDecl::Import(ImportDecl {
|
||||
src: Str {
|
||||
span: DUMMY_SP,
|
||||
value: js_word!(""),
|
||||
..
|
||||
},
|
||||
..
|
||||
})) => false,
|
||||
_ => true,
|
||||
..
|
||||
}))
|
||||
)
|
||||
});
|
||||
|
||||
m
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::Versions;
|
||||
use serde::{de, de::Visitor, Deserialize, Deserializer};
|
||||
use std::{cmp, cmp::Ordering, fmt, hash, str::FromStr};
|
||||
use std::{cmp, cmp::Ordering, fmt, str::FromStr};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct Version {
|
||||
|
@ -5697,7 +5697,6 @@ test!(
|
||||
|_| decorators(decorators::Config {
|
||||
legacy: true,
|
||||
emit_metadata: true,
|
||||
..Default::default()
|
||||
}),
|
||||
issue_1421_1,
|
||||
"
|
||||
@ -5730,7 +5729,6 @@ test!(
|
||||
|_| decorators(decorators::Config {
|
||||
legacy: true,
|
||||
emit_metadata: true,
|
||||
..Default::default()
|
||||
}),
|
||||
issue_1456_1,
|
||||
"
|
||||
@ -5824,7 +5822,6 @@ test!(
|
||||
|_| decorators(decorators::Config {
|
||||
legacy: true,
|
||||
emit_metadata: true,
|
||||
..Default::default()
|
||||
}),
|
||||
issue_1278_1,
|
||||
"
|
||||
@ -5992,7 +5989,6 @@ test_exec!(
|
||||
|_| simple_strip(Config {
|
||||
legacy: true,
|
||||
emit_metadata: true,
|
||||
..Default::default()
|
||||
}),
|
||||
issue_1362_1,
|
||||
"
|
||||
@ -6056,7 +6052,6 @@ fn fixture(input: PathBuf) {
|
||||
decorators(Config {
|
||||
legacy: true,
|
||||
emit_metadata: true,
|
||||
..Default::default()
|
||||
})
|
||||
)
|
||||
},
|
||||
|
@ -71,15 +71,11 @@ pub fn doc_str(attr: &Attribute) -> Option<String> {
|
||||
}
|
||||
}
|
||||
|
||||
match *attr {
|
||||
Attribute { .. } => {
|
||||
if !is_attr_name(attr, "doc") {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(parse_tts(attr))
|
||||
}
|
||||
if !is_attr_name(attr, "doc") {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(parse_tts(attr))
|
||||
}
|
||||
|
||||
/// fail! is a panic! with location reporting.
|
||||
|
@ -81,48 +81,45 @@ impl SwcLoader {
|
||||
tracing::debug!("JsLoader.load({})", name);
|
||||
let helpers = Helpers::new(false);
|
||||
|
||||
match name {
|
||||
FileName::Custom(id) => {
|
||||
// Handle built-in modules
|
||||
if id.starts_with("node:") {
|
||||
let fm = self
|
||||
.compiler
|
||||
.cm
|
||||
.new_source_file(name.clone(), "".to_string());
|
||||
return Ok(ModuleData {
|
||||
fm,
|
||||
module: Module {
|
||||
span: DUMMY_SP,
|
||||
body: Default::default(),
|
||||
shebang: Default::default(),
|
||||
},
|
||||
helpers: Default::default(),
|
||||
});
|
||||
// Handle disabled modules, eg when `browser` has a field
|
||||
// set to `false`
|
||||
} else {
|
||||
// TODO: When we know the calling context is ESM
|
||||
// TODO: switch to `export default {}`.
|
||||
let fm = self
|
||||
.compiler
|
||||
.cm
|
||||
.new_source_file(name.clone(), "module.exports = {}".to_string());
|
||||
let lexer = Lexer::new(
|
||||
Syntax::Es(Default::default()),
|
||||
Default::default(),
|
||||
StringInput::from(&*fm),
|
||||
None,
|
||||
);
|
||||
let mut parser = Parser::new_from(lexer);
|
||||
let module = parser.parse_module().unwrap();
|
||||
return Ok(ModuleData {
|
||||
fm,
|
||||
module,
|
||||
helpers: Default::default(),
|
||||
});
|
||||
}
|
||||
if let FileName::Custom(id) = name {
|
||||
// Handle built-in modules
|
||||
if id.starts_with("node:") {
|
||||
let fm = self
|
||||
.compiler
|
||||
.cm
|
||||
.new_source_file(name.clone(), "".to_string());
|
||||
return Ok(ModuleData {
|
||||
fm,
|
||||
module: Module {
|
||||
span: DUMMY_SP,
|
||||
body: Default::default(),
|
||||
shebang: Default::default(),
|
||||
},
|
||||
helpers: Default::default(),
|
||||
});
|
||||
// Handle disabled modules, eg when `browser` has a field
|
||||
// set to `false`
|
||||
} else {
|
||||
// TODO: When we know the calling context is ESM
|
||||
// TODO: switch to `export default {}`.
|
||||
let fm = self
|
||||
.compiler
|
||||
.cm
|
||||
.new_source_file(name.clone(), "module.exports = {}".to_string());
|
||||
let lexer = Lexer::new(
|
||||
Syntax::Es(Default::default()),
|
||||
Default::default(),
|
||||
StringInput::from(&*fm),
|
||||
None,
|
||||
);
|
||||
let mut parser = Parser::new_from(lexer);
|
||||
let module = parser.parse_module().unwrap();
|
||||
return Ok(ModuleData {
|
||||
fm,
|
||||
module,
|
||||
helpers: Default::default(),
|
||||
});
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let fm = self
|
||||
@ -134,21 +131,18 @@ impl SwcLoader {
|
||||
})
|
||||
.with_context(|| format!("failed to load file `{}`", name))?;
|
||||
|
||||
match name {
|
||||
FileName::Real(path) => {
|
||||
if let Some(ext) = path.extension() {
|
||||
if ext == "json" {
|
||||
let module = load_json_as_module(&fm)
|
||||
.with_context(|| format!("failed to load json file at {}", fm.name))?;
|
||||
return Ok(ModuleData {
|
||||
fm,
|
||||
module,
|
||||
helpers: Default::default(),
|
||||
});
|
||||
}
|
||||
if let FileName::Real(path) = name {
|
||||
if let Some(ext) = path.extension() {
|
||||
if ext == "json" {
|
||||
let module = load_json_as_module(&fm)
|
||||
.with_context(|| format!("failed to load json file at {}", fm.name))?;
|
||||
return Ok(ModuleData {
|
||||
fm,
|
||||
module,
|
||||
helpers: Default::default(),
|
||||
});
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
tracing::trace!("JsLoader.load: loaded");
|
||||
@ -214,15 +208,9 @@ impl SwcLoader {
|
||||
filename: String::new(),
|
||||
config_file: None,
|
||||
root: None,
|
||||
root_mode: Default::default(),
|
||||
swcrc: true,
|
||||
swcrc_roots: Default::default(),
|
||||
env_name: { env::var("NODE_ENV").unwrap_or_else(|_| "development".into()) },
|
||||
source_maps: None,
|
||||
source_file_name: None,
|
||||
source_root: None,
|
||||
is_module: IsModule::Bool(true),
|
||||
output_path: None,
|
||||
..Default::default()
|
||||
},
|
||||
&fm.name,
|
||||
|
@ -22,8 +22,8 @@ impl Prefixer {
|
||||
important: Option<Span>,
|
||||
) {
|
||||
match v {
|
||||
Value::Function(f) => match &*f.name.value {
|
||||
"image-set" => {
|
||||
Value::Function(f) => {
|
||||
if &*f.name.value == "image-set" {
|
||||
let val = Value::Function(Function {
|
||||
span: DUMMY_SP,
|
||||
name: Ident {
|
||||
@ -67,9 +67,7 @@ impl Prefixer {
|
||||
important,
|
||||
});
|
||||
}
|
||||
|
||||
_ => {}
|
||||
},
|
||||
}
|
||||
|
||||
Value::Comma(c) => {
|
||||
if !c.values.is_empty() {
|
||||
@ -224,60 +222,48 @@ impl VisitMut for Prefixer {
|
||||
|
||||
"background" => {
|
||||
if !n.value.is_empty() {
|
||||
match &n.value[0] {
|
||||
Value::Function(f) => match &*f.name.value {
|
||||
"image-set" => {
|
||||
let val = Value::Function(Function {
|
||||
if let Value::Function(f) = &n.value[0] {
|
||||
if &*f.name.value == "image-set" {
|
||||
let val = Value::Function(Function {
|
||||
span: DUMMY_SP,
|
||||
name: Ident {
|
||||
span: DUMMY_SP,
|
||||
name: Ident {
|
||||
span: DUMMY_SP,
|
||||
value: "-webkit-image-set".into(),
|
||||
raw: "-webkit-image-set".into(),
|
||||
},
|
||||
value: f.value.clone(),
|
||||
});
|
||||
self.added.push(Declaration {
|
||||
span: n.span,
|
||||
property: n.property.clone(),
|
||||
value: vec![val],
|
||||
important: n.important,
|
||||
});
|
||||
}
|
||||
|
||||
_ => {}
|
||||
},
|
||||
|
||||
_ => {}
|
||||
value: "-webkit-image-set".into(),
|
||||
raw: "-webkit-image-set".into(),
|
||||
},
|
||||
value: f.value.clone(),
|
||||
});
|
||||
self.added.push(Declaration {
|
||||
span: n.span,
|
||||
property: n.property.clone(),
|
||||
value: vec![val],
|
||||
important: n.important,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"background-image" => {
|
||||
if !n.value.is_empty() {
|
||||
match &n.value[0] {
|
||||
Value::Function(f) => match &*f.name.value {
|
||||
"image-set" => {
|
||||
let val = Value::Function(Function {
|
||||
if let Value::Function(f) = &n.value[0] {
|
||||
if let "image-set" = &*f.name.value {
|
||||
let val = Value::Function(Function {
|
||||
span: DUMMY_SP,
|
||||
name: Ident {
|
||||
span: DUMMY_SP,
|
||||
name: Ident {
|
||||
span: DUMMY_SP,
|
||||
value: "-webkit-image-set".into(),
|
||||
raw: "-webkit-image-set".into(),
|
||||
},
|
||||
value: f.value.clone(),
|
||||
});
|
||||
self.added.push(Declaration {
|
||||
span: n.span,
|
||||
property: n.property.clone(),
|
||||
value: vec![val],
|
||||
important: n.important,
|
||||
});
|
||||
}
|
||||
|
||||
_ => {}
|
||||
},
|
||||
|
||||
_ => {}
|
||||
value: "-webkit-image-set".into(),
|
||||
raw: "-webkit-image-set".into(),
|
||||
},
|
||||
value: f.value.clone(),
|
||||
});
|
||||
self.added.push(Declaration {
|
||||
span: n.span,
|
||||
property: n.property.clone(),
|
||||
value: vec![val],
|
||||
important: n.important,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -285,13 +271,11 @@ impl VisitMut for Prefixer {
|
||||
"cursor" => {
|
||||
if !n.value.is_empty() {
|
||||
match &n.value[0] {
|
||||
Value::Ident(Ident { value, .. }) => match &**value {
|
||||
"grab" => {
|
||||
Value::Ident(Ident { value, .. }) => {
|
||||
if &**value == "grab" {
|
||||
same_name!("-webkit-grab");
|
||||
}
|
||||
|
||||
_ => {}
|
||||
},
|
||||
}
|
||||
|
||||
_ => {
|
||||
let second = n.value.get(1).cloned();
|
||||
@ -303,8 +287,8 @@ impl VisitMut for Prefixer {
|
||||
|
||||
"display" => {
|
||||
if n.value.len() == 1 {
|
||||
match &n.value[0] {
|
||||
Value::Ident(Ident { value, .. }) => match &**value {
|
||||
if let Value::Ident(Ident { value, .. }) = &n.value[0] {
|
||||
match &**value {
|
||||
"flex" => {
|
||||
same_name!("-webkit-box");
|
||||
same_name!("-webkit-flex");
|
||||
@ -318,9 +302,7 @@ impl VisitMut for Prefixer {
|
||||
}
|
||||
|
||||
_ => {}
|
||||
},
|
||||
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -364,8 +346,8 @@ impl VisitMut for Prefixer {
|
||||
|
||||
"justify-content" => {
|
||||
if n.value.len() == 1 {
|
||||
match &n.value[0] {
|
||||
Value::Ident(Ident { value, .. }) => match &**value {
|
||||
if let Value::Ident(Ident { value, .. }) = &n.value[0] {
|
||||
match &**value {
|
||||
"flex-end" => {
|
||||
simple!("-webkit-box-pack", "end");
|
||||
simple!("-ms-flex-pack", "end");
|
||||
@ -386,9 +368,7 @@ impl VisitMut for Prefixer {
|
||||
}
|
||||
|
||||
_ => {}
|
||||
},
|
||||
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -463,15 +443,10 @@ impl VisitMut for Prefixer {
|
||||
|
||||
"position" => {
|
||||
if n.value.len() == 1 {
|
||||
match &n.value[0] {
|
||||
Value::Ident(Ident { value, .. }) => match &**value {
|
||||
"sticky" => {
|
||||
same_name!("-webkit-sticky");
|
||||
}
|
||||
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
if let Value::Ident(Ident { value, .. }) = &n.value[0] {
|
||||
if &**value == "sticky" {
|
||||
same_name!("-webkit-sticky");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -490,34 +465,22 @@ impl VisitMut for Prefixer {
|
||||
|
||||
"text-decoration" => {
|
||||
if n.value.len() == 1 {
|
||||
match &n.value[0] {
|
||||
Value::Ident(Ident { value, .. }) => match &**value {
|
||||
"none" => {
|
||||
same_content!("-webkit-text-decoration");
|
||||
}
|
||||
|
||||
_ => {}
|
||||
},
|
||||
|
||||
_ => {}
|
||||
if let Value::Ident(Ident { value, .. }) = &n.value[0] {
|
||||
if &**value == "none" {
|
||||
same_content!("-webkit-text-decoration");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"text-size-adjust" => {
|
||||
if n.value.len() == 1 {
|
||||
match &n.value[0] {
|
||||
Value::Ident(Ident { value, .. }) => match &**value {
|
||||
"none" => {
|
||||
same_content!("-webkit-text-size-adjust");
|
||||
same_content!("-moz-text-size-adjust");
|
||||
same_content!("-ms-text-size-adjust");
|
||||
}
|
||||
|
||||
_ => {}
|
||||
},
|
||||
|
||||
_ => {}
|
||||
if let Value::Ident(Ident { value, .. }) = &n.value[0] {
|
||||
if &**value == "none" {
|
||||
same_content!("-webkit-text-size-adjust");
|
||||
same_content!("-moz-text-size-adjust");
|
||||
same_content!("-ms-text-size-adjust");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -539,8 +502,8 @@ impl VisitMut for Prefixer {
|
||||
|
||||
"writing-mode" => {
|
||||
if n.value.len() == 1 {
|
||||
match &n.value[0] {
|
||||
Value::Ident(Ident { value, .. }) => match &**value {
|
||||
if let Value::Ident(Ident { value, .. }) = &n.value[0] {
|
||||
match &**value {
|
||||
"none" => {
|
||||
same_content!("-webkit-writing-mode");
|
||||
same_content!("-ms-writing-mode");
|
||||
@ -562,9 +525,7 @@ impl VisitMut for Prefixer {
|
||||
}
|
||||
|
||||
_ => {}
|
||||
},
|
||||
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -572,8 +533,8 @@ impl VisitMut for Prefixer {
|
||||
"min-width" | "width" | "max-width" | "min-height" | "height" | "max-height"
|
||||
| "min-block-size" | "min-inline-size" => {
|
||||
if n.value.len() == 1 {
|
||||
match &n.value[0] {
|
||||
Value::Ident(Ident { value, .. }) => match &**value {
|
||||
if let Value::Ident(Ident { value, .. }) = &n.value[0] {
|
||||
match &**value {
|
||||
"fit-content" => {
|
||||
same_name!("-webkit-fit-content");
|
||||
same_name!("-moz-fit-content");
|
||||
@ -601,8 +562,7 @@ impl VisitMut for Prefixer {
|
||||
}
|
||||
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ fn make(mode: Mode, stmts: &[Stmt]) -> Quote {
|
||||
let sig = create_method_sig(mode, ty);
|
||||
let name = sig.ident.clone();
|
||||
let s = name.to_string();
|
||||
if methods.iter().any(|m| m.sig.ident == &*s) {
|
||||
if methods.iter().any(|m| m.sig.ident == *s) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1290,27 +1290,24 @@ fn create_method_body(mode: Mode, ty: &Type) -> Block {
|
||||
GenericArgument::Type(arg) => {
|
||||
let ident = method_name(mode, arg);
|
||||
|
||||
match mode {
|
||||
Mode::Fold => {
|
||||
if let Some(..) = as_box(arg) {
|
||||
return q!(
|
||||
Vars { ident },
|
||||
({
|
||||
match n {
|
||||
Some(n) => Some(
|
||||
swc_visit::util::map::Map::map(
|
||||
n,
|
||||
|n| _visitor.ident(n),
|
||||
),
|
||||
),
|
||||
None => None,
|
||||
if mode == Mode::Fold {
|
||||
if let Some(..) = as_box(arg) {
|
||||
return q!(
|
||||
Vars { ident },
|
||||
({
|
||||
match n {
|
||||
Some(n) => {
|
||||
Some(swc_visit::util::map::Map::map(
|
||||
n,
|
||||
|n| _visitor.ident(n),
|
||||
))
|
||||
}
|
||||
})
|
||||
)
|
||||
.parse();
|
||||
}
|
||||
None => None,
|
||||
}
|
||||
})
|
||||
)
|
||||
.parse();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
return match mode {
|
||||
@ -1477,15 +1474,12 @@ fn add_required(types: &mut Vec<Type>, ty: &Type) {
|
||||
}
|
||||
|
||||
fn is_option(ty: &Type) -> bool {
|
||||
match ty {
|
||||
Type::Path(p) => {
|
||||
let last = p.path.segments.last().unwrap();
|
||||
if let Type::Path(p) = ty {
|
||||
let last = p.path.segments.last().unwrap();
|
||||
|
||||
if !last.arguments.is_empty() && last.ident == "Option" {
|
||||
return true;
|
||||
}
|
||||
if !last.arguments.is_empty() && last.ident == "Option" {
|
||||
return true;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
false
|
||||
@ -1496,25 +1490,22 @@ fn as_box(ty: &Type) -> Option<&Type> {
|
||||
}
|
||||
|
||||
fn extract_generic<'a>(name: &str, ty: &'a Type) -> Option<&'a Type> {
|
||||
match ty {
|
||||
Type::Path(p) => {
|
||||
let last = p.path.segments.last().unwrap();
|
||||
if let Type::Path(p) = ty {
|
||||
let last = p.path.segments.last().unwrap();
|
||||
|
||||
if !last.arguments.is_empty() && last.ident == name {
|
||||
match &last.arguments {
|
||||
PathArguments::AngleBracketed(tps) => {
|
||||
let arg = tps.args.first().unwrap();
|
||||
if !last.arguments.is_empty() && last.ident == name {
|
||||
match &last.arguments {
|
||||
PathArguments::AngleBracketed(tps) => {
|
||||
let arg = tps.args.first().unwrap();
|
||||
|
||||
match arg {
|
||||
GenericArgument::Type(arg) => return Some(arg),
|
||||
_ => unimplemented!("generic parameter other than type"),
|
||||
}
|
||||
match arg {
|
||||
GenericArgument::Type(arg) => return Some(arg),
|
||||
_ => unimplemented!("generic parameter other than type"),
|
||||
}
|
||||
_ => unimplemented!("Box() -> T or Box without a type parameter"),
|
||||
}
|
||||
_ => unimplemented!("Box() -> T or Box without a type parameter"),
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
None
|
||||
|
@ -21,57 +21,50 @@ pub struct Config {
|
||||
impl Parse for Config {
|
||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||
fn update(c: &mut Config, meta: Meta) {
|
||||
match &meta {
|
||||
Meta::List(list) => {
|
||||
if list
|
||||
.path
|
||||
.get_ident()
|
||||
.map(|i| *i == "exclude")
|
||||
.unwrap_or(false)
|
||||
{
|
||||
//
|
||||
macro_rules! fail {
|
||||
() => {{
|
||||
fail!("invalid input to the attribute")
|
||||
}};
|
||||
($inner:expr) => {{
|
||||
panic!(
|
||||
"{}\nnote: exclude() expects one or more comma-separated \
|
||||
regular expressions, like exclude(\".*\\\\.d\\\\.ts\") or \
|
||||
if let Meta::List(list) = &meta {
|
||||
if list
|
||||
.path
|
||||
.get_ident()
|
||||
.map(|i| *i == "exclude")
|
||||
.unwrap_or(false)
|
||||
{
|
||||
//
|
||||
macro_rules! fail {
|
||||
() => {{
|
||||
fail!("invalid input to the attribute")
|
||||
}};
|
||||
($inner:expr) => {{
|
||||
panic!(
|
||||
"{}\nnote: exclude() expects one or more comma-separated regular \
|
||||
expressions, like exclude(\".*\\\\.d\\\\.ts\") or \
|
||||
exclude(\".*\\\\.d\\\\.ts\", \".*\\\\.tsx\")",
|
||||
$inner
|
||||
)
|
||||
}};
|
||||
}
|
||||
$inner
|
||||
)
|
||||
}};
|
||||
}
|
||||
|
||||
if list.nested.is_empty() {
|
||||
fail!("empty exclude()")
|
||||
}
|
||||
if list.nested.is_empty() {
|
||||
fail!("empty exclude()")
|
||||
}
|
||||
|
||||
for token in list.nested.iter() {
|
||||
match token {
|
||||
NestedMeta::Meta(_) => fail!(),
|
||||
NestedMeta::Lit(lit) => {
|
||||
let lit = match lit {
|
||||
Lit::Str(v) => v.value(),
|
||||
_ => fail!(),
|
||||
};
|
||||
c.exclude_patterns.push(Regex::new(&lit).unwrap_or_else(
|
||||
|err| {
|
||||
fail!(format!(
|
||||
"failed to parse regex: {}\n{}",
|
||||
lit, err
|
||||
))
|
||||
},
|
||||
));
|
||||
}
|
||||
for token in list.nested.iter() {
|
||||
match token {
|
||||
NestedMeta::Meta(_) => fail!(),
|
||||
NestedMeta::Lit(lit) => {
|
||||
let lit = match lit {
|
||||
Lit::Str(v) => v.value(),
|
||||
_ => fail!(),
|
||||
};
|
||||
c.exclude_patterns
|
||||
.push(Regex::new(&lit).unwrap_or_else(|err| {
|
||||
fail!(format!("failed to parse regex: {}\n{}", lit, err))
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let expected = r#"#[fixture("fixture/**/*.ts", exclude("*\.d\.ts"))]"#;
|
||||
@ -177,13 +170,10 @@ pub fn expand(callee: &Ident, attr: Config) -> Result<Vec<ItemFn>, Error> {
|
||||
|
||||
if !ignored {
|
||||
f.attrs.retain(|attr| {
|
||||
match attr.path.get_ident() {
|
||||
Some(name) => {
|
||||
if name == "ignore" {
|
||||
return false;
|
||||
}
|
||||
if let Some(name) = attr.path.get_ident() {
|
||||
if name == "ignore" {
|
||||
return false;
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
|
||||
true
|
||||
|
Loading…
Reference in New Issue
Block a user