Skip to content
Merged
135 changes: 135 additions & 0 deletions src/analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,15 @@ impl ImportAttributes {
pub enum DynamicDependencyKind {
#[default]
Import,
ImportSource,
Require,
}

#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum StaticDependencyKind {
Import,
ImportSource,
ImportType,
ImportEquals,
Export,
Expand Down Expand Up @@ -926,6 +928,32 @@ mod test {
);
}

#[test]
fn static_dependency_descriptor_import_source_serialization() {
let descriptor = DependencyDescriptor::Static(StaticDependencyDescriptor {
kind: StaticDependencyKind::ImportSource,
types_specifier: None,
specifier: "./test".to_string(),
specifier_range: PositionRange {
start: Position::zeroed(),
end: Position::zeroed(),
},
import_attributes: ImportAttributes::None,
is_side_effect: false,
});
run_serialization_test(
&descriptor,
// WARNING: Deserialization MUST be backwards compatible in order
// to load data from JSR.
json!({
"type": "static",
"kind": "importSource",
"specifier": "./test",
"specifierRange": [[0, 0], [0, 0]],
}),
);
}

#[test]
fn dynamic_dependency_descriptor_serialization() {
run_serialization_test(
Expand Down Expand Up @@ -980,6 +1008,32 @@ mod test {
);
}

#[test]
fn dynamic_dependency_descriptor_import_source_serialization() {
let descriptor =
DependencyDescriptor::Dynamic(DynamicDependencyDescriptor {
kind: DynamicDependencyKind::ImportSource,
types_specifier: None,
argument: DynamicArgument::String("test".to_string()),
argument_range: PositionRange {
start: Position::zeroed(),
end: Position::zeroed(),
},
import_attributes: ImportAttributes::None,
});
run_serialization_test(
&descriptor,
// WARNING: Deserialization MUST be backwards compatible in order
// to load data from JSR.
json!({
"type": "dynamic",
"kind": "importSource",
"argument": "test",
"argumentRange": [[0, 0], [0, 0]],
}),
);
}

#[test]
fn test_dynamic_argument_serialization() {
run_serialization_test(
Expand Down Expand Up @@ -1129,6 +1183,87 @@ mod test {
run_v1_deserialization_test(json, &expected);
}

#[test]
fn test_v1_to_v2_deserialization_import_source_static() {
let expected = ModuleInfo {
is_script: false,
dependencies: vec![DependencyDescriptor::Static(
StaticDependencyDescriptor {
kind: StaticDependencyKind::ImportSource,
specifier: "./a.js".to_string(),
specifier_range: PositionRange {
start: Position {
line: 1,
character: 2,
},
end: Position {
line: 3,
character: 4,
},
},
types_specifier: None,
import_attributes: ImportAttributes::None,
is_side_effect: false,
},
)],
ts_references: Vec::new(),
self_types_specifier: None,
jsx_import_source: None,
jsx_import_source_types: None,
jsdoc_imports: Vec::new(),
source_map_url: None,
};
let json = json!({
"dependencies": [{
"type": "static",
"kind": "importSource",
"specifier": "./a.js",
"specifierRange": [[1, 2], [3, 4]],
}],
});
run_v1_deserialization_test(json, &expected);
}

#[test]
fn test_v1_to_v2_deserialization_import_source_dynamic() {
let expected = ModuleInfo {
is_script: false,
dependencies: vec![DependencyDescriptor::Dynamic(
DynamicDependencyDescriptor {
kind: DynamicDependencyKind::ImportSource,
types_specifier: None,
argument: DynamicArgument::String("./a.js".to_string()),
argument_range: PositionRange {
start: Position {
line: 1,
character: 2,
},
end: Position {
line: 3,
character: 4,
},
},
import_attributes: ImportAttributes::None,
},
)],
ts_references: Vec::new(),
self_types_specifier: None,
jsx_import_source: None,
jsx_import_source_types: None,
jsdoc_imports: Vec::new(),
source_map_url: None,
};
let json = json!({
"dependencies": [{
"type": "dynamic",
"kind": "importSource",
"argument": "./a.js",
"argumentRange": [[1, 2], [3, 4]],
}],
});
run_v1_deserialization_test(json, &expected);
}

#[test]
fn module_info_serialization_source_map_url() {
let module_info = ModuleInfo {
Expand Down
29 changes: 16 additions & 13 deletions src/ast/dep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use deno_ast::SourceRangedForSpanned;
use deno_ast::swc::ast;
use deno_ast::swc::ast::Callee;
use deno_ast::swc::ast::Expr;
use deno_ast::swc::ast::ImportPhase;
use deno_ast::swc::atoms::Atom;
use deno_ast::swc::common::comments::CommentKind;
use deno_ast::swc::ecma_visit::Visit;
Expand Down Expand Up @@ -145,10 +146,11 @@ impl DependencyCollector<'_> {
impl Visit for DependencyCollector<'_> {
fn visit_import_decl(&mut self, node: &ast::ImportDecl) {
let leading_comments = self.get_leading_comments(node.start());
let kind = if node.type_only {
StaticDependencyKind::ImportType
} else {
StaticDependencyKind::Import
let kind = match (node.type_only, node.phase) {
(true, _) => StaticDependencyKind::ImportType,
(false, ImportPhase::Evaluation) => StaticDependencyKind::Import,
(false, ImportPhase::Source) => StaticDependencyKind::ImportSource,
(false, ImportPhase::Defer) => return,
};
self.items.push(
StaticDependencyDescriptor {
Expand Down Expand Up @@ -241,10 +243,15 @@ impl Visit for DependencyCollector<'_> {
fn visit_call_expr(&mut self, node: &ast::CallExpr) {
node.visit_children_with(self);

let is_esm = matches!(&node.callee, Callee::Import(_));
if !is_esm && !self.is_require(&node.callee) {
return;
}
let kind = match &node.callee {
Callee::Import(import) => match import.phase {
ImportPhase::Evaluation => DynamicDependencyKind::Import,
ImportPhase::Source => DynamicDependencyKind::ImportSource,
ImportPhase::Defer => return,
},
_ if self.is_require(&node.callee) => DynamicDependencyKind::Require,
_ => return,
};
let Some(arg) = node.args.first() else {
return;
};
Expand Down Expand Up @@ -332,11 +339,7 @@ impl Visit for DependencyCollector<'_> {
let leading_comments = self.get_leading_comments(node.start());
self.items.push(
DynamicDependencyDescriptor {
kind: if is_esm {
DynamicDependencyKind::Import
} else {
DynamicDependencyKind::Require
},
kind,
leading_comments,
range: node.range(),
argument,
Expand Down
Loading