Skip to content

Commit

Permalink
fix(es/dep_graph): Fix parsing of import assertions (#3005)
Browse files Browse the repository at this point in the history
  • Loading branch information
bartlomieju authored Dec 11, 2021
1 parent cabf5a4 commit 819fc88
Showing 1 changed file with 81 additions and 9 deletions.
90 changes: 81 additions & 9 deletions crates/swc_ecma_dep_graph/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,14 +171,46 @@ impl<'a> Visit for DependencyCollector<'a> {
if let ast::Lit::Str(str_) = lit {
let specifier = str_.value.clone();
let leading_comments = self.get_leading_comments(node.span);
let mut import_assertions = HashMap::default();

if let Some(arg) = node.args.get(1) {
if let Object(object_lit) = &*arg.expr {
for prop in object_lit.props.iter() {
if let ast::PropOrSpread::Prop(prop) = prop {
if let ast::Prop::KeyValue(key_value) = &**prop {
let maybe_key = match &key_value.key {
ast::PropName::Str(key) => Some(key.value.to_string()),
ast::PropName::Ident(ident) => {
Some(ident.sym.to_string())
}
_ => None,
};

if let Some(key) = maybe_key {
if key == "assert" {
import_assertions = if let Object(assertions_lit) =
&*key_value.value
{
parse_import_assertions(Some(&assertions_lit))
} else {
HashMap::new()
};
}
}
}
}
}
}
}

self.items.push(DependencyDescriptor {
kind,
is_dynamic,
leading_comments,
span: node.span,
specifier,
specifier_span: str_.span,
import_assertions: HashMap::default(),
import_assertions,
});
}
}
Expand All @@ -192,13 +224,23 @@ impl<'a> Visit for DependencyCollector<'a> {
fn parse_import_assertions(asserts: Option<&ast::ObjectLit>) -> HashMap<String, String> {
let mut import_assertions = HashMap::new();
if let Some(asserts) = asserts {
for prop in &asserts.props {
let prop = prop.clone().expect_prop();
let key_value = prop.expect_key_value();
let key = key_value.key.expect_str().value.to_string();
let value_lit = key_value.value.expect_lit();
if let ast::Lit::Str(str_) = value_lit {
import_assertions.insert(key, str_.value.to_string());
for prop in asserts.props.iter() {
if let ast::PropOrSpread::Prop(prop) = prop {
if let ast::Prop::KeyValue(key_value) = &**prop {
let maybe_key = match &key_value.key {
ast::PropName::Str(key) => Some(key.value.to_string()),
ast::PropName::Ident(ident) => Some(ident.sym.to_string()),
_ => None,
};

if let Some(key) = maybe_key {
if let ast::Expr::Lit(value_lit) = &*key_value.value {
if let ast::Lit::Str(str_) = value_lit {
import_assertions.insert(key, str_.value.to_string());
}
}
}
}
}
}
}
Expand Down Expand Up @@ -392,14 +434,17 @@ try {
let source = r#"import * as bar from "./test.ts" assert { "type": "typescript" };
export * from "./test.ts" assert { "type": "typescript" };
export { bar } from "./test.json" assert { "type": "json" };
import foo from "./foo.json" assert { type: "json" };
const fizz = await import("./fizz.json", { "assert": { type: "json" } });
const buzz = await import("./buzz.json", { assert: { "type": "json" } });
"#;
let (module, comments) = helper("test.ts", &source).unwrap();
let mut expected_assertions1 = HashMap::new();
expected_assertions1.insert("type".to_string(), "typescript".to_string());
let mut expected_assertions2 = HashMap::new();
expected_assertions2.insert("type".to_string(), "json".to_string());
let dependencies = analyze_dependencies(&module, &comments);
assert_eq!(dependencies.len(), 3);
assert_eq!(dependencies.len(), 6);
assert_eq!(
dependencies,
vec![
Expand Down Expand Up @@ -428,6 +473,33 @@ export { bar } from "./test.json" assert { "type": "json" };
span: Span::new(BytePos(125), BytePos(185), Default::default()),
specifier: JsWord::from("./test.json"),
specifier_span: Span::new(BytePos(145), BytePos(158), Default::default()),
import_assertions: expected_assertions2.clone(),
},
DependencyDescriptor {
kind: DependencyKind::Import,
is_dynamic: false,
leading_comments: Vec::new(),
span: Span::new(BytePos(186), BytePos(239), Default::default()),
specifier: JsWord::from("./foo.json"),
specifier_span: Span::new(BytePos(202), BytePos(214), Default::default()),
import_assertions: expected_assertions2.clone(),
},
DependencyDescriptor {
kind: DependencyKind::Import,
is_dynamic: true,
leading_comments: Vec::new(),
span: Span::new(BytePos(259), BytePos(312), Default::default()),
specifier: JsWord::from("./fizz.json"),
specifier_span: Span::new(BytePos(266), BytePos(279), Default::default()),
import_assertions: expected_assertions2.clone(),
},
DependencyDescriptor {
kind: DependencyKind::Import,
is_dynamic: true,
leading_comments: Vec::new(),
span: Span::new(BytePos(333), BytePos(386), Default::default()),
specifier: JsWord::from("./buzz.json"),
specifier_span: Span::new(BytePos(340), BytePos(353), Default::default()),
import_assertions: expected_assertions2,
},
]
Expand Down

1 comment on commit 819fc88

@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: 819fc88 Previous: 8340a86 Ratio
full_es2015 180610979 ns/iter (± 6290317) 224795035 ns/iter (± 15433207) 0.80
full_es2016 147862763 ns/iter (± 5073066) 178171304 ns/iter (± 11823617) 0.83
full_es2017 150002994 ns/iter (± 6729359) 186242251 ns/iter (± 17203012) 0.81
full_es2018 149782695 ns/iter (± 6257510) 183350550 ns/iter (± 14751190) 0.82
full_es2019 148317773 ns/iter (± 6907600) 183671787 ns/iter (± 13207074) 0.81
full_es2020 147243599 ns/iter (± 6257939) 181205276 ns/iter (± 12757532) 0.81
full_es3 204202738 ns/iter (± 15456983) 267976298 ns/iter (± 22993949) 0.76
full_es5 190177123 ns/iter (± 10641776) 246374520 ns/iter (± 18671395) 0.77
parser 676445 ns/iter (± 8220) 896133 ns/iter (± 96782) 0.75

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

Please sign in to comment.