feat(es/codegen): Optimize output of new expressions without arguments (#3800)

This commit is contained in:
Austaras 2022-03-01 18:55:49 +08:00 committed by GitHub
parent d25ac78865
commit e1b13eb21a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 60 additions and 25 deletions

File diff suppressed because one or more lines are too long

View File

@ -76,6 +76,8 @@ mod tests {
assert_min("++foo", "++foo");
assert_min("--foo", "--foo");
assert_min("new foo", "new foo");
assert_min("new foo()", "new foo");
assert_min("new foo().bar()", "new foo().bar()");
assert_min("void foo", "void foo");
assert_min("typeof foo", "typeof foo");
}

View File

@ -582,7 +582,13 @@ where
#[emitter]
fn emit_callee(&mut self, node: &Callee) -> Result {
match *node {
Callee::Expr(ref e) => emit!(e),
Callee::Expr(ref e) => {
if let Expr::New(new) = &**e {
self.emit_new(new, false)?;
} else {
emit!(e);
}
}
Callee::Super(ref n) => emit!(n),
Callee::Import(ref n) => emit!(n),
}
@ -663,7 +669,11 @@ where
}
}
OptChainBase::Call(ref e) => {
emit!(e.callee);
if let Expr::New(new) = &*e.callee {
self.emit_new(new, false)?;
} else {
emit!(e.callee);
}
punct!("?.");
punct!("(");
@ -691,40 +701,58 @@ where
punct!(")");
}
#[emitter]
fn emit_new_expr(&mut self, node: &NewExpr) -> Result {
fn emit_new(&mut self, node: &NewExpr, should_ignore_empty_args: bool) -> Result {
self.emit_leading_comments_of_span(node.span(), false)?;
{
let span = self.cm.span_until_char(node.span, ' ');
keyword!(span, "new");
keyword!(self, span, "new");
}
let starts_with_alpha_num = node.callee.starts_with_alpha_num();
if starts_with_alpha_num {
space!();
space!(self);
} else {
formatting_space!();
formatting_space!(self);
}
emit!(node.callee);
emit!(self, node.callee);
if let Some(type_args) = &node.type_args {
emit!(type_args);
emit!(self, type_args);
}
if let Some(ref args) = node.args {
punct!("(");
self.emit_expr_or_spreads(node.span(), args, ListFormat::NewExpressionArguments)?;
punct!(")");
if !(self.cfg.minify && args.is_empty() && should_ignore_empty_args) {
punct!(self, "(");
self.emit_expr_or_spreads(node.span(), args, ListFormat::NewExpressionArguments)?;
punct!(self, ")");
}
}
// if it's false, it means it doesn't come from emit_expr,
// we need to compensate that
if !should_ignore_empty_args && self.comments.is_some() {
self.emit_trailing_comments_of_pos(node.span().hi, true, true)?;
}
Ok(())
}
#[emitter]
fn emit_new_expr(&mut self, node: &NewExpr) -> Result {
self.emit_new(node, true)?;
}
#[emitter]
fn emit_member_expr(&mut self, node: &MemberExpr) -> Result {
self.emit_leading_comments_of_span(node.span(), false)?;
emit!(node.obj);
if let Expr::New(new) = &*node.obj {
self.emit_new(new, false)?;
} else {
emit!(node.obj);
}
match &node.prop {
MemberProp::Computed(computed) => emit!(computed),
@ -1469,7 +1497,12 @@ where
fn emit_tagged_tpl_lit(&mut self, node: &TaggedTpl) -> Result {
self.emit_leading_comments_of_span(node.span(), false)?;
emit!(node.tag);
if let Expr::New(new) = &*node.tag {
self.emit_new(new, false)?;
} else {
emit!(node.tag);
}
emit!(node.type_params);
emit!(node.tpl);
}

View File

@ -1 +1 @@
class a{b(){new super.c()}}
class a{b(){new super.c}}

View File

@ -1 +1 @@
new a.b()
new a.b

View File

@ -1 +1 @@
function a(){b();c();return d()}function e(){b();c();throw new f()}
function a(){b();c();return d()}function e(){b();c();throw new f}

View File

@ -1 +1 @@
(function(){var a;if(b)return;a=new c();return a})()(function(){var a;if(b)return;a=new c();return a})()(function(){var a;if(b)return;a=new c();return a})()
(function(){var a;if(b)return;a=new c;return a})()(function(){var a;if(b)return;a=new c;return a})()(function(){var a;if(b)return;a=new c;return a})()

View File

@ -1 +1 @@
new new a()
new new a

View File

@ -1 +1 @@
class a extends b{c(){new super.d()}}
class a extends b{c(){new super.d}}

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
class a extends BaseSchema{matches(d,a){let e=!1,b,c;return a&&("object"==typeof a?{excludeEmptyString:e=!1,message:b,name:c}=a:b=a),this.test({name:c||"matches",message:b||string.matches,params:{regex:d},test:a=>isAbsent(a)||""===a&&e|| -1!==a.search(d)})}}(function(){return new a()}).prototype=a.prototype
class a extends BaseSchema{matches(d,a){let e=!1,b,c;return a&&("object"==typeof a?{excludeEmptyString:e=!1,message:b,name:c}=a:b=a),this.test({name:c||"matches",message:b||string.matches,params:{regex:d},test:a=>isAbsent(a)||""===a&&e|| -1!==a.search(d)})}}(function(){return new a}).prototype=a.prototype