summaryrefslogtreecommitdiff
path: root/cli/swc_util.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/swc_util.rs')
-rw-r--r--cli/swc_util.rs439
1 files changed, 0 insertions, 439 deletions
diff --git a/cli/swc_util.rs b/cli/swc_util.rs
index 77ac6d083..906d9f9bd 100644
--- a/cli/swc_util.rs
+++ b/cli/swc_util.rs
@@ -1,8 +1,6 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-use crate::doc::Location;
use crate::msg::MediaType;
use crate::swc_common;
-use crate::swc_common::comments::CommentKind;
use crate::swc_common::comments::Comments;
use crate::swc_common::errors::Diagnostic;
use crate::swc_common::errors::DiagnosticBuilder;
@@ -26,8 +24,6 @@ use std::error::Error;
use std::fmt;
use std::sync::Arc;
use std::sync::RwLock;
-use swc_ecma_visit::Node;
-use swc_ecma_visit::Visit;
fn get_default_es_config() -> EsConfig {
let mut config = EsConfig::default();
@@ -231,438 +227,3 @@ impl AstParser {
}
}
}
-
-struct DependencyVisitor {
- dependencies: Vec<String>,
- analyze_dynamic_imports: bool,
-}
-
-impl Visit for DependencyVisitor {
- fn visit_import_decl(
- &mut self,
- import_decl: &swc_ecma_ast::ImportDecl,
- _parent: &dyn Node,
- ) {
- let src_str = import_decl.src.value.to_string();
- self.dependencies.push(src_str);
- }
-
- fn visit_named_export(
- &mut self,
- named_export: &swc_ecma_ast::NamedExport,
- _parent: &dyn Node,
- ) {
- if let Some(src) = &named_export.src {
- let src_str = src.value.to_string();
- self.dependencies.push(src_str);
- }
- }
-
- fn visit_export_all(
- &mut self,
- export_all: &swc_ecma_ast::ExportAll,
- _parent: &dyn Node,
- ) {
- let src_str = export_all.src.value.to_string();
- self.dependencies.push(src_str);
- }
-
- fn visit_call_expr(
- &mut self,
- call_expr: &swc_ecma_ast::CallExpr,
- _parent: &dyn Node,
- ) {
- if !self.analyze_dynamic_imports {
- return;
- }
-
- use swc_ecma_ast::Expr::*;
- use swc_ecma_ast::ExprOrSuper::*;
-
- 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_ecma_ast::Lit::Str(str_) = lit {
- let src_str = str_.value.to_string();
- self.dependencies.push(src_str);
- }
- }
- _ => return,
- }
- }
- }
-}
-
-#[derive(Clone, Debug, PartialEq)]
-enum DependencyKind {
- Import,
- DynamicImport,
- Export,
-}
-
-#[derive(Clone, Debug, PartialEq)]
-struct DependencyDescriptor {
- span: Span,
- specifier: String,
- kind: DependencyKind,
-}
-
-struct NewDependencyVisitor {
- dependencies: Vec<DependencyDescriptor>,
-}
-
-impl Visit for NewDependencyVisitor {
- fn visit_import_decl(
- &mut self,
- import_decl: &swc_ecma_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_ecma_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_ecma_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_ecma_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_ecma_ast::CallExpr,
- parent: &dyn Node,
- ) {
- use swc_ecma_ast::Expr::*;
- use swc_ecma_ast::ExprOrSuper::*;
-
- swc_ecma_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_ecma_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,
- }
- }
- }
-}
-
-fn get_deno_types(parser: &AstParser, span: Span) -> Option<String> {
- let comments = parser.get_span_comments(span);
-
- if comments.is_empty() {
- return None;
- }
-
- // @deno-types must directly prepend import statement - hence
- // checking last comment for span
- let last = comments.last().unwrap();
- let comment = last.text.trim_start();
-
- if comment.starts_with("@deno-types") {
- let split: Vec<String> =
- comment.split('=').map(|s| s.to_string()).collect();
- assert_eq!(split.len(), 2);
- let specifier_in_quotes = split.get(1).unwrap().to_string();
- let specifier = specifier_in_quotes
- .trim_start_matches('\"')
- .trim_start_matches('\'')
- .trim_end_matches('\"')
- .trim_end_matches('\'')
- .to_string();
- return Some(specifier);
- }
-
- None
-}
-
-#[derive(Clone, Debug, PartialEq)]
-pub struct ImportDescriptor {
- pub specifier: String,
- pub deno_types: Option<String>,
- pub location: Location,
-}
-
-#[derive(Clone, Debug, PartialEq)]
-pub enum TsReferenceKind {
- Lib,
- Types,
- Path,
-}
-
-#[derive(Clone, Debug, PartialEq)]
-pub struct TsReferenceDescriptor {
- pub kind: TsReferenceKind,
- pub specifier: String,
- pub location: Location,
-}
-
-pub fn analyze_dependencies_and_references(
- file_name: &str,
- media_type: MediaType,
- source_code: &str,
- analyze_dynamic_imports: bool,
-) -> Result<
- (Vec<ImportDescriptor>, Vec<TsReferenceDescriptor>),
- SwcDiagnosticBuffer,
-> {
- let parser = AstParser::new();
- parser.parse_module(file_name, media_type, source_code, |parse_result| {
- let module = parse_result?;
- let mut collector = NewDependencyVisitor {
- dependencies: vec![],
- };
- let module_span = module.span;
- collector.visit_module(&module, &module);
-
- let dependency_descriptors = collector.dependencies;
-
- // for each import check if there's relevant @deno-types directive
- let imports = dependency_descriptors
- .iter()
- .filter(|desc| {
- if analyze_dynamic_imports {
- return true;
- }
-
- desc.kind != DependencyKind::DynamicImport
- })
- .map(|desc| {
- let location = parser.get_span_location(desc.span);
- let deno_types = get_deno_types(&parser, desc.span);
- ImportDescriptor {
- specifier: desc.specifier.to_string(),
- deno_types,
- location: location.into(),
- }
- })
- .collect();
-
- // analyze comment from beginning of the file and find TS directives
- let comments = parser
- .comments
- .take_leading_comments(module_span.lo())
- .unwrap_or_else(Vec::new);
-
- let mut references = vec![];
- for comment in comments {
- if comment.kind != CommentKind::Line {
- continue;
- }
-
- // TODO(bartlomieju): you can do better than that...
- let text = comment.text.to_string();
- let (kind, specifier_in_quotes) =
- if text.starts_with("/ <reference path=") {
- (
- TsReferenceKind::Path,
- text.trim_start_matches("/ <reference path="),
- )
- } else if text.starts_with("/ <reference lib=") {
- (
- TsReferenceKind::Lib,
- text.trim_start_matches("/ <reference lib="),
- )
- } else if text.starts_with("/ <reference types=") {
- (
- TsReferenceKind::Types,
- text.trim_start_matches("/ <reference types="),
- )
- } else {
- continue;
- };
- let specifier = specifier_in_quotes
- .trim_end_matches("/>")
- .trim_end()
- .trim_start_matches('\"')
- .trim_start_matches('\'')
- .trim_end_matches('\"')
- .trim_end_matches('\'')
- .to_string();
-
- let location = parser.get_span_location(comment.span);
- references.push(TsReferenceDescriptor {
- kind,
- specifier,
- location: location.into(),
- });
- }
- Ok((imports, references))
- })
-}
-
-#[test]
-fn test_analyze_dependencies_and_directives() {
- let source = r#"
-// This comment is placed to make sure that directives are parsed
-// even when they start on non-first line
-
-/// <reference lib="dom" />
-/// <reference types="./type_reference.d.ts" />
-/// <reference path="./type_reference/dep.ts" />
-// @deno-types="./type_definitions/foo.d.ts"
-import { foo } from "./type_definitions/foo.js";
-// @deno-types="./type_definitions/fizz.d.ts"
-import "./type_definitions/fizz.js";
-
-/// <reference path="./type_reference/dep2.ts" />
-
-import * as qat from "./type_definitions/qat.ts";
-
-console.log(foo);
-console.log(fizz);
-console.log(qat.qat);
-"#;
-
- let (imports, references) = analyze_dependencies_and_references(
- "some/file.ts",
- MediaType::TypeScript,
- source,
- true,
- )
- .expect("Failed to parse");
-
- assert_eq!(
- imports,
- vec![
- ImportDescriptor {
- specifier: "./type_definitions/foo.js".to_string(),
- deno_types: Some("./type_definitions/foo.d.ts".to_string()),
- location: Location {
- filename: "some/file.ts".to_string(),
- line: 9,
- col: 0,
- },
- },
- ImportDescriptor {
- specifier: "./type_definitions/fizz.js".to_string(),
- deno_types: Some("./type_definitions/fizz.d.ts".to_string()),
- location: Location {
- filename: "some/file.ts".to_string(),
- line: 11,
- col: 0,
- },
- },
- ImportDescriptor {
- specifier: "./type_definitions/qat.ts".to_string(),
- deno_types: None,
- location: Location {
- filename: "some/file.ts".to_string(),
- line: 15,
- col: 0,
- },
- },
- ]
- );
-
- // According to TS docs (https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html)
- // directives that are not at the top of the file are ignored, so only
- // 3 references should be captured instead of 4.
- assert_eq!(
- references,
- vec![
- TsReferenceDescriptor {
- specifier: "dom".to_string(),
- kind: TsReferenceKind::Lib,
- location: Location {
- filename: "some/file.ts".to_string(),
- line: 5,
- col: 0,
- },
- },
- TsReferenceDescriptor {
- specifier: "./type_reference.d.ts".to_string(),
- kind: TsReferenceKind::Types,
- location: Location {
- filename: "some/file.ts".to_string(),
- line: 6,
- col: 0,
- },
- },
- TsReferenceDescriptor {
- specifier: "./type_reference/dep.ts".to_string(),
- kind: TsReferenceKind::Path,
- location: Location {
- filename: "some/file.ts".to_string(),
- line: 7,
- col: 0,
- },
- },
- ]
- );
-}