summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBartek IwaƄczuk <biwanczuk@gmail.com>2020-09-03 17:11:30 +0200
committerGitHub <noreply@github.com>2020-09-03 17:11:30 +0200
commitdbd941148c472171eacec364c689a2a50fa0653d (patch)
tree570fc2620c72415baabf7f47dca71201602c4881
parent5b100cb874a23f22bcdcbf1965d6f916c7487ae4 (diff)
refactor: use dependency analyzer from SWC (#7334)
-rw-r--r--Cargo.lock13
-rw-r--r--cli/Cargo.toml1
-rw-r--r--cli/tsc.rs152
3 files changed, 31 insertions, 135 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 33d353626..d51e476bf 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -412,6 +412,7 @@ dependencies = [
"serde_json",
"sourcemap",
"swc_common",
+ "swc_ecma_dep_graph",
"swc_ecmascript",
"sys-info",
"tempfile",
@@ -2261,6 +2262,18 @@ dependencies = [
]
[[package]]
+name = "swc_ecma_dep_graph"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb38c4567ac35d625c0da0a70d68449e38b23c1ae95df9ca6837811e2711136e"
+dependencies = [
+ "swc_atoms",
+ "swc_common",
+ "swc_ecma_ast",
+ "swc_ecma_visit",
+]
+
+[[package]]
name = "swc_ecma_parser"
version = "0.37.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/cli/Cargo.toml b/cli/Cargo.toml
index 0d61cceed..74694c165 100644
--- a/cli/Cargo.toml
+++ b/cli/Cargo.toml
@@ -63,6 +63,7 @@ sys-info = "0.7.0"
sourcemap = "6.0.1"
swc_common = { version = "=0.10.2", features = ["sourcemap"] }
swc_ecmascript = { version = "=0.7.0", features = ["codegen", "parser", "react", "transforms", "visit"] }
+swc_ecma_dep_graph = "0.3.0"
tempfile = "3.1.0"
termcolor = "1.1.0"
tokio = { version = "0.2.22", features = ["full"] }
diff --git a/cli/tsc.rs b/cli/tsc.rs
index 799673694..eff925062 100644
--- a/cli/tsc.rs
+++ b/cli/tsc.rs
@@ -55,10 +55,9 @@ use std::sync::atomic::Ordering;
use std::sync::Arc;
use std::sync::Mutex;
use std::task::Poll;
+use swc_common::comments::Comment;
use swc_common::comments::CommentKind;
-use swc_common::Span;
-use swc_ecmascript::visit::Node;
-use swc_ecmascript::visit::Visit;
+use swc_ecma_dep_graph as dep_graph;
use url::Url;
pub const AVAILABLE_LIBS: &[&str] = &[
@@ -1438,121 +1437,6 @@ pub async fn runtime_transpile(
}
#[derive(Clone, Debug, PartialEq)]
-enum DependencyKind {
- Import,
- DynamicImport,
- Export,
-}
-
-#[derive(Clone, Debug, PartialEq)]
-struct DependencyDescriptor {
- span: Span,
- specifier: String,
- kind: DependencyKind,
-}
-
-struct DependencyVisitor {
- dependencies: Vec<DependencyDescriptor>,
-}
-
-impl Visit for DependencyVisitor {
- fn visit_import_decl(
- &mut self,
- import_decl: &swc_ecmascript::ast::ImportDecl,
- _parent: &dyn Node,
- ) {
- let src_str = import_decl.src.value.to_string();
- self.dependencies.push(DependencyDescriptor {
- specifier: src_str,
- kind: DependencyKind::Import,
- span: import_decl.span,
- });
- }
-
- fn visit_named_export(
- &mut self,
- named_export: &swc_ecmascript::ast::NamedExport,
- _parent: &dyn Node,
- ) {
- if let Some(src) = &named_export.src {
- let src_str = src.value.to_string();
- self.dependencies.push(DependencyDescriptor {
- specifier: src_str,
- kind: DependencyKind::Export,
- span: named_export.span,
- });
- }
- }
-
- fn visit_export_all(
- &mut self,
- export_all: &swc_ecmascript::ast::ExportAll,
- _parent: &dyn Node,
- ) {
- let src_str = export_all.src.value.to_string();
- self.dependencies.push(DependencyDescriptor {
- specifier: src_str,
- kind: DependencyKind::Export,
- span: export_all.span,
- });
- }
-
- fn visit_ts_import_type(
- &mut self,
- ts_import_type: &swc_ecmascript::ast::TsImportType,
- _parent: &dyn Node,
- ) {
- // TODO(bartlomieju): possibly add separate DependencyKind
- let src_str = ts_import_type.arg.value.to_string();
- self.dependencies.push(DependencyDescriptor {
- specifier: src_str,
- kind: DependencyKind::Import,
- span: ts_import_type.arg.span,
- });
- }
-
- fn visit_call_expr(
- &mut self,
- call_expr: &swc_ecmascript::ast::CallExpr,
- parent: &dyn Node,
- ) {
- use swc_ecmascript::ast::Expr::*;
- use swc_ecmascript::ast::ExprOrSuper::*;
-
- swc_ecmascript::visit::visit_call_expr(self, call_expr, parent);
- let boxed_expr = match call_expr.callee.clone() {
- Super(_) => return,
- Expr(boxed) => boxed,
- };
-
- match &*boxed_expr {
- Ident(ident) => {
- if &ident.sym.to_string() != "import" {
- return;
- }
- }
- _ => return,
- };
-
- if let Some(arg) = call_expr.args.get(0) {
- match &*arg.expr {
- Lit(lit) => {
- if let swc_ecmascript::ast::Lit::Str(str_) = lit {
- let src_str = str_.value.to_string();
- self.dependencies.push(DependencyDescriptor {
- specifier: src_str,
- kind: DependencyKind::DynamicImport,
- span: call_expr.span,
- });
- }
- }
- _ => return,
- }
- }
- }
-}
-
-#[derive(Clone, Debug, PartialEq)]
pub struct ImportDesc {
pub specifier: String,
pub deno_types: Option<String>,
@@ -1587,39 +1471,39 @@ pub fn pre_process_file(
let parser = AstParser::default();
let parse_result = parser.parse_module(file_name, media_type, source_code);
let module = parse_result?;
- let mut collector = DependencyVisitor {
- dependencies: vec![],
- };
- let module_span = module.span;
- collector.visit_module(&module, &module);
- let dependency_descriptors = collector.dependencies;
+ let dependency_descriptors = dep_graph::analyze_dependencies(
+ &module,
+ &parser.source_map,
+ &parser.comments,
+ );
// for each import check if there's relevant @deno-types directive
let imports = dependency_descriptors
.iter()
+ .filter(|desc| desc.kind != dep_graph::DependencyKind::Require)
.filter(|desc| {
if analyze_dynamic_imports {
return true;
}
-
- desc.kind != DependencyKind::DynamicImport
+ !desc.is_dynamic
})
.map(|desc| {
- let location = parser.get_span_location(desc.span);
- let deno_types = get_deno_types(&parser, desc.span);
+ let deno_types = get_deno_types(&desc.leading_comments);
ImportDesc {
specifier: desc.specifier.to_string(),
deno_types,
- location: location.into(),
+ location: Location {
+ filename: file_name.to_string(),
+ col: desc.col,
+ line: desc.line,
+ },
}
})
.collect();
// analyze comment from beginning of the file and find TS directives
- let comments = parser
- .comments
- .with_leading(module_span.lo(), |cmts| cmts.to_vec());
+ let comments = parser.get_span_comments(module.span);
let mut references = vec![];
for comment in comments {
@@ -1640,9 +1524,7 @@ pub fn pre_process_file(
Ok((imports, references))
}
-fn get_deno_types(parser: &AstParser, span: Span) -> Option<String> {
- let comments = parser.get_span_comments(span);
-
+fn get_deno_types(comments: &[Comment]) -> Option<String> {
if comments.is_empty() {
return None;
}