Skip to content

Commit

Permalink
feat(es/parser): Add allow_return_outside_function to options (#5046)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-akait committed Jun 29, 2022
1 parent b364828 commit 37eb366
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 18 deletions.
15 changes: 14 additions & 1 deletion crates/swc_ecma_parser/src/lib.rs
Expand Up @@ -246,7 +246,7 @@ impl Syntax {
}
}

pub fn allow_super_outside_method(self) -> bool {
pub(crate) fn allow_super_outside_method(self) -> bool {
match self {
Syntax::Es(EsConfig {
allow_super_outside_method,
Expand All @@ -256,6 +256,16 @@ impl Syntax {
}
}

pub(crate) fn allow_return_outside_function(self) -> bool {
match self {
Syntax::Es(EsConfig {
allow_return_outside_function,
..
}) => allow_return_outside_function,
Syntax::Typescript(_) => false,
}
}

pub(crate) fn early_errors(self) -> bool {
match self {
Syntax::Typescript(t) => !t.no_early_errors,
Expand Down Expand Up @@ -315,6 +325,9 @@ pub struct EsConfig {

#[serde(default, rename = "allowSuperOutsideMethod")]
pub allow_super_outside_method: bool,

#[serde(default, rename = "allowReturnOutsideFunction")]
pub allow_return_outside_function: bool,
}

/// Syntactic context.
Expand Down
2 changes: 1 addition & 1 deletion crates/swc_ecma_parser/src/parser/stmt.rs
Expand Up @@ -562,7 +562,7 @@ impl<'a, I: Tokens> Parser<I> {
}))
});

if !self.ctx().in_function {
if !self.ctx().in_function && !self.input.syntax().allow_return_outside_function() {
self.emit_err(span!(self, start), SyntaxError::ReturnNotAllowed);
}

Expand Down
31 changes: 17 additions & 14 deletions crates/swc_html_minifier/src/lib.rs
Expand Up @@ -1055,13 +1055,17 @@ impl Minifier {

// TODO source map url output for JS and CSS?
// TODO allow preserve comments
fn minify_js(&self, data: String, is_module: bool) -> Option<String> {
fn minify_js(&self, data: String, is_module: bool, is_attribute: bool) -> Option<String> {
let mut errors: Vec<_> = vec![];

let cm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
let fm = cm.new_source_file(FileName::Anon, data);

let syntax = swc_ecma_parser::Syntax::Es(Default::default());
let syntax = swc_ecma_parser::Syntax::Es(swc_ecma_parser::EsConfig {
allow_return_outside_function: !is_module && is_attribute,
..Default::default()
});

let target = swc_ecma_ast::EsVersion::latest();
let mut program = if is_module {
match swc_ecma_parser::parse_file_as_module(&fm, syntax, target, None, &mut errors) {
Expand All @@ -1075,6 +1079,11 @@ impl Minifier {
}
};

// Avoid compress potential invalid JS
if !errors.is_empty() {
return None;
}

let unresolved_mark = Mark::new();
let top_level_mark = Mark::new();

Expand All @@ -1083,11 +1092,6 @@ impl Minifier {
&mut swc_ecma_transforms_base::resolver(unresolved_mark, top_level_mark, false),
);

// Avoid compress potential invalid JS
if !errors.is_empty() {
return None;
}

let options = swc_ecma_minifier::option::MinifyOptions {
compress: Some(swc_ecma_minifier::option::CompressOptions {
ecma: target,
Expand Down Expand Up @@ -1657,8 +1661,8 @@ impl VisitMut for Minifier {
}

value = values.join(" ");
} else if self.minify_js && self.is_event_handler_attribute(&n.name) {
value = match self.minify_js(value.clone(), false) {
} else if self.is_event_handler_attribute(&n.name) {
value = match self.minify_js(value.clone(), false, true) {
Some(minified) => minified,
_ => value,
};
Expand All @@ -1681,13 +1685,13 @@ impl VisitMut for Minifier {

match minifier_type {
Some(MinifierType::JsScript) if self.minify_js => {
value = match self.minify_js(value.clone(), false) {
value = match self.minify_js(value.clone(), false, true) {
Some(minified) => minified,
_ => value,
};
}
Some(MinifierType::JsModule) if self.minify_js => {
value = match self.minify_js(value.clone(), true) {
value = match self.minify_js(value.clone(), true, true) {
Some(minified) => minified,
_ => value,
};
Expand Down Expand Up @@ -1818,15 +1822,15 @@ impl VisitMut for Minifier {

match text_type {
Some(MinifierType::JsScript) => {
let minified = match self.minify_js(n.data.to_string(), false) {
let minified = match self.minify_js(n.data.to_string(), false, false) {
Some(minified) => minified,
None => return,
};

n.data = minified.into();
}
Some(MinifierType::JsModule) => {
let minified = match self.minify_js(n.data.to_string(), true) {
let minified = match self.minify_js(n.data.to_string(), true, false) {
Some(minified) => minified,
None => return,
};
Expand Down Expand Up @@ -1937,7 +1941,6 @@ fn create_minifier(context_element: Option<&Element>, options: &MinifyOptions) -
minify_js: options.minify_js,
minify_json: options.minify_json,
minify_css: options.minify_css,

minify_additional_attributes: options.minify_additional_attributes.clone(),
minify_additional_scripts_content: options.minify_additional_scripts_content.clone(),
}
Expand Down
Expand Up @@ -15,5 +15,8 @@
style="width:100%; height:100%; position:absolute; top:0; left:0; z-index:-1;">
<circle onmouseover=" javascript:alert('test') " cx="50" cy="50" r="30" style="fill:url(#gradient)" />
</svg>
<div type="text" onmouseover="javascript:myFunction()">test</div>
<a href="https://datacadamia.com" onclick="console.log(`Navigation to ${this.href}` + ` cancelled`); return false;">Click me</a>
<a href="https://datacadamia.com" onclick="javascript:console.log(`Navigation to ${this.href}` + ` cancelled`); return false;">Click me</a>
</body>
</html>
Expand Up @@ -6,4 +6,7 @@
<div type=text>test</div>
<svg version=1.1 viewBox="0 0 100 100" preserveAspectRatio="xMidYMid slice" style=width:100%;height:100%;position:absolute;top:0;left:0;z-index:-1>
<circle onmouseover='alert("test")' cx=50 cy=50 r=30 style=fill:url(#gradient) />
</svg>
</svg>
<div type=text onmouseover=myFunction()>test</div>
<a href=https://datacadamia.com onclick="console.log(`Navigation to ${this.href} cancelled`);return false">Click me</a>
<a href=https://datacadamia.com onclick="console.log(`Navigation to ${this.href} cancelled`);return false">Click me</a>
@@ -1,2 +1,2 @@
<!doctype html><html lang=en><meta charset=UTF-8><meta name=viewport content="width=device-width,user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0"><meta http-equiv=X-UA-Compatible content="ie=edge"><title>Document</title><a href=http://www.google.co.uk/ onclick="return (confirm('Follow' + ' this link?'))">Google</a>
<!doctype html><html lang=en><meta charset=UTF-8><meta name=viewport content="width=device-width,user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0"><meta http-equiv=X-UA-Compatible content="ie=edge"><title>Document</title><a href=http://www.google.co.uk/ onclick='return confirm("Follow this link?")'>Google</a>
<a href=http://www.google.co.uk/ onclick='alert("testtest")'>Google</a>

1 comment on commit 37eb366

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: 37eb366 Previous: 2e139f1 Ratio
es/full/minify/libraries/antd 1611688054 ns/iter (± 34880078) 1598090234 ns/iter (± 120729858) 1.01
es/full/minify/libraries/d3 408947317 ns/iter (± 8702381) 387933276 ns/iter (± 18649284) 1.05
es/full/minify/libraries/echarts 1616676754 ns/iter (± 28378701) 1573205227 ns/iter (± 56641799) 1.03
es/full/minify/libraries/jquery 88842176 ns/iter (± 3546112) 84773129 ns/iter (± 9545938) 1.05
es/full/minify/libraries/lodash 118955893 ns/iter (± 3618300) 111387514 ns/iter (± 4664599) 1.07
es/full/minify/libraries/moment 52464927 ns/iter (± 1500861) 49954211 ns/iter (± 1790175) 1.05
es/full/minify/libraries/react 17266991 ns/iter (± 387842) 17317196 ns/iter (± 632632) 1.00
es/full/minify/libraries/terser 600576627 ns/iter (± 8122486) 570877488 ns/iter (± 13074394) 1.05
es/full/minify/libraries/three 539213594 ns/iter (± 3253418) 520773333 ns/iter (± 8703477) 1.04
es/full/minify/libraries/typescript 3411915071 ns/iter (± 41710358) 3331149938 ns/iter (± 71886157) 1.02
es/full/minify/libraries/victory 716878445 ns/iter (± 9831378) 696542765 ns/iter (± 19511375) 1.03
es/full/minify/libraries/vue 135643691 ns/iter (± 2384318) 128645727 ns/iter (± 7451414) 1.05
es/full/codegen/es3 31897 ns/iter (± 606) 30461 ns/iter (± 1097) 1.05
es/full/codegen/es5 31820 ns/iter (± 801) 30462 ns/iter (± 1614) 1.04
es/full/codegen/es2015 31889 ns/iter (± 442) 30864 ns/iter (± 1586) 1.03
es/full/codegen/es2016 31903 ns/iter (± 453) 30737 ns/iter (± 1005) 1.04
es/full/codegen/es2017 31823 ns/iter (± 505) 30386 ns/iter (± 686) 1.05
es/full/codegen/es2018 31604 ns/iter (± 821) 30161 ns/iter (± 1565) 1.05
es/full/codegen/es2019 31748 ns/iter (± 1001) 30391 ns/iter (± 935) 1.04
es/full/codegen/es2020 31691 ns/iter (± 1423) 30235 ns/iter (± 1055) 1.05
es/full/all/es3 190063899 ns/iter (± 5026586) 177382501 ns/iter (± 4841909) 1.07
es/full/all/es5 176181189 ns/iter (± 7788535) 166295076 ns/iter (± 5152485) 1.06
es/full/all/es2015 143890058 ns/iter (± 4944295) 135673456 ns/iter (± 3794241) 1.06
es/full/all/es2016 145196750 ns/iter (± 6266643) 134230869 ns/iter (± 6042529) 1.08
es/full/all/es2017 139220533 ns/iter (± 5388065) 133801672 ns/iter (± 3246701) 1.04
es/full/all/es2018 138401317 ns/iter (± 4378116) 132147741 ns/iter (± 6354587) 1.05
es/full/all/es2019 140306059 ns/iter (± 4521637) 131958575 ns/iter (± 2908998) 1.06
es/full/all/es2020 134672073 ns/iter (± 5647985) 127159964 ns/iter (± 4034007) 1.06
es/full/parser 724852 ns/iter (± 12409) 681717 ns/iter (± 18763) 1.06
es/full/base/fixer 29742 ns/iter (± 328) 28467 ns/iter (± 1449) 1.04
es/full/base/resolver_and_hygiene 87552 ns/iter (± 3221) 85362 ns/iter (± 4373) 1.03
serialization of ast node 215 ns/iter (± 5) 194 ns/iter (± 12) 1.11
serialization of serde 229 ns/iter (± 1) 215 ns/iter (± 6) 1.07

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.