summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock18
-rw-r--r--cli/Cargo.toml2
-rw-r--r--cli/doc/class.rs339
-rw-r--r--cli/doc/display.rs91
-rw-r--r--cli/doc/enum.rs40
-rw-r--r--cli/doc/function.rs58
-rw-r--r--cli/doc/interface.rs303
-rw-r--r--cli/doc/mod.rs75
-rw-r--r--cli/doc/module.rs59
-rw-r--r--cli/doc/namespace.rs67
-rw-r--r--cli/doc/node.rs287
-rw-r--r--cli/doc/params.rs289
-rw-r--r--cli/doc/parser.rs505
-rw-r--r--cli/doc/printer.rs426
-rw-r--r--cli/doc/tests.rs2002
-rw-r--r--cli/doc/ts_type.rs985
-rw-r--r--cli/doc/ts_type_param.rs71
-rw-r--r--cli/doc/type_alias.rs30
-rw-r--r--cli/doc/variable.rs39
-rw-r--r--cli/global_state.rs2
-rw-r--r--cli/main.rs58
-rw-r--r--cli/module_graph.rs2
-rw-r--r--cli/swc_util.rs26
-rw-r--r--cli/tsc.rs2
24 files changed, 93 insertions, 5683 deletions
diff --git a/Cargo.lock b/Cargo.lock
index cfbe630f1..c220be9a9 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -329,6 +329,7 @@ dependencies = [
"bytes",
"clap",
"deno_core",
+ "deno_doc",
"deno_lint",
"deno_web",
"dissimilar",
@@ -393,6 +394,23 @@ dependencies = [
]
[[package]]
+name = "deno_doc"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c1700f692f75fb14c854ca5e2b5e74c23c5b5cc2b3ea9adec4ff0cd5693deab0"
+dependencies = [
+ "futures",
+ "lazy_static",
+ "regex",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "swc_common",
+ "swc_ecmascript",
+ "termcolor",
+]
+
+[[package]]
name = "deno_lint"
version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/cli/Cargo.toml b/cli/Cargo.toml
index c9371352f..d35ce7951 100644
--- a/cli/Cargo.toml
+++ b/cli/Cargo.toml
@@ -24,9 +24,9 @@ winapi = "0.3.9"
[dependencies]
deno_core = { path = "../core", version = "0.53.0" }
+deno_doc = { version = "0.1.0" }
deno_lint = { version = "0.1.23", features = ["json"] }
-
atty = "0.2.14"
base64 = "0.12.3"
bytes = "0.5.6"
diff --git a/cli/doc/class.rs b/cli/doc/class.rs
deleted file mode 100644
index 292aa4b97..000000000
--- a/cli/doc/class.rs
+++ /dev/null
@@ -1,339 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-use crate::colors;
-use crate::doc::display::{
- display_abstract, display_accessibility, display_async, display_generator,
- display_method, display_optional, display_readonly, display_static,
- SliceDisplayer,
-};
-use serde::Serialize;
-use swc_common::Spanned;
-
-use super::function::function_to_function_def;
-use super::function::FunctionDef;
-use super::interface::expr_to_name;
-use super::params::{
- assign_pat_to_param_def, ident_to_param_def, pat_to_param_def,
- prop_name_to_string, ts_fn_param_to_param_def,
-};
-use super::parser::DocParser;
-use super::ts_type::{
- maybe_type_param_instantiation_to_type_defs, ts_type_ann_to_def, TsTypeDef,
-};
-use super::ts_type_param::maybe_type_param_decl_to_type_param_defs;
-use super::ts_type_param::TsTypeParamDef;
-use super::Location;
-use super::ParamDef;
-
-use std::fmt::{Display, Formatter, Result as FmtResult};
-
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct ClassConstructorDef {
- pub js_doc: Option<String>,
- pub accessibility: Option<swc_ecmascript::ast::Accessibility>,
- pub name: String,
- pub params: Vec<ParamDef>,
- pub location: Location,
-}
-
-impl Display for ClassConstructorDef {
- fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
- write!(
- f,
- "{}{}({})",
- display_accessibility(self.accessibility),
- colors::magenta("constructor"),
- SliceDisplayer::new(&self.params, ", ", false),
- )
- }
-}
-
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct ClassPropertyDef {
- pub js_doc: Option<String>,
- pub ts_type: Option<TsTypeDef>,
- pub readonly: bool,
- pub accessibility: Option<swc_ecmascript::ast::Accessibility>,
- pub optional: bool,
- pub is_abstract: bool,
- pub is_static: bool,
- pub name: String,
- pub location: Location,
-}
-
-impl Display for ClassPropertyDef {
- fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
- write!(
- f,
- "{}{}{}{}{}{}",
- display_abstract(self.is_abstract),
- display_accessibility(self.accessibility),
- display_static(self.is_static),
- display_readonly(self.readonly),
- colors::bold(&self.name),
- display_optional(self.optional),
- )?;
- if let Some(ts_type) = &self.ts_type {
- write!(f, ": {}", ts_type)?;
- }
- Ok(())
- }
-}
-
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct ClassIndexSignatureDef {
- pub readonly: bool,
- pub params: Vec<ParamDef>,
- pub ts_type: Option<TsTypeDef>,
-}
-
-impl Display for ClassIndexSignatureDef {
- fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
- write!(
- f,
- "{}[{}]",
- display_readonly(self.readonly),
- SliceDisplayer::new(&self.params, ", ", false)
- )?;
- if let Some(ts_type) = &self.ts_type {
- write!(f, ": {}", ts_type)?;
- }
- Ok(())
- }
-}
-
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct ClassMethodDef {
- pub js_doc: Option<String>,
- pub accessibility: Option<swc_ecmascript::ast::Accessibility>,
- pub optional: bool,
- pub is_abstract: bool,
- pub is_static: bool,
- pub name: String,
- pub kind: swc_ecmascript::ast::MethodKind,
- pub function_def: FunctionDef,
- pub location: Location,
-}
-
-impl Display for ClassMethodDef {
- fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
- write!(
- f,
- "{}{}{}{}{}{}{}{}({})",
- display_abstract(self.is_abstract),
- display_accessibility(self.accessibility),
- display_static(self.is_static),
- display_async(self.function_def.is_async),
- display_method(self.kind),
- display_generator(self.function_def.is_generator),
- colors::bold(&self.name),
- display_optional(self.optional),
- SliceDisplayer::new(&self.function_def.params, ", ", false),
- )?;
- if let Some(return_type) = &self.function_def.return_type {
- write!(f, ": {}", return_type)?;
- }
- Ok(())
- }
-}
-
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct ClassDef {
- // TODO(bartlomieju): decorators
- pub is_abstract: bool,
- pub constructors: Vec<ClassConstructorDef>,
- pub properties: Vec<ClassPropertyDef>,
- pub index_signatures: Vec<ClassIndexSignatureDef>,
- pub methods: Vec<ClassMethodDef>,
- pub extends: Option<String>,
- pub implements: Vec<TsTypeDef>,
- pub type_params: Vec<TsTypeParamDef>,
- pub super_type_params: Vec<TsTypeDef>,
-}
-
-pub fn class_to_class_def(
- doc_parser: &DocParser,
- class: &swc_ecmascript::ast::Class,
-) -> ClassDef {
- let mut constructors = vec![];
- let mut methods = vec![];
- let mut properties = vec![];
- let mut index_signatures = vec![];
-
- let extends: Option<String> = match &class.super_class {
- Some(boxed) => {
- use swc_ecmascript::ast::Expr;
- let expr: &Expr = &**boxed;
- match expr {
- Expr::Ident(ident) => Some(ident.sym.to_string()),
- _ => None,
- }
- }
- None => None,
- };
-
- let implements = class
- .implements
- .iter()
- .map(|expr| expr.into())
- .collect::<Vec<TsTypeDef>>();
-
- for member in &class.body {
- use swc_ecmascript::ast::ClassMember::*;
-
- match member {
- Constructor(ctor) => {
- let ctor_js_doc = doc_parser.js_doc_for_span(ctor.span());
- let constructor_name = prop_name_to_string(
- &ctor.key,
- Some(&doc_parser.ast_parser.source_map),
- );
-
- let mut params = vec![];
-
- for param in &ctor.params {
- use swc_ecmascript::ast::ParamOrTsParamProp::*;
-
- let param_def = match param {
- Param(param) => pat_to_param_def(
- &param.pat,
- Some(&doc_parser.ast_parser.source_map),
- ),
- TsParamProp(ts_param_prop) => {
- use swc_ecmascript::ast::TsParamPropParam;
-
- match &ts_param_prop.param {
- TsParamPropParam::Ident(ident) => ident_to_param_def(
- ident,
- Some(&doc_parser.ast_parser.source_map),
- ),
- TsParamPropParam::Assign(assign_pat) => {
- assign_pat_to_param_def(
- assign_pat,
- Some(&doc_parser.ast_parser.source_map),
- )
- }
- }
- }
- };
- params.push(param_def);
- }
-
- let constructor_def = ClassConstructorDef {
- js_doc: ctor_js_doc,
- accessibility: ctor.accessibility,
- name: constructor_name,
- params,
- location: doc_parser.ast_parser.get_span_location(ctor.span).into(),
- };
- constructors.push(constructor_def);
- }
- Method(class_method) => {
- let method_js_doc = doc_parser.js_doc_for_span(class_method.span());
- let method_name = prop_name_to_string(
- &class_method.key,
- Some(&doc_parser.ast_parser.source_map),
- );
- let fn_def =
- function_to_function_def(&doc_parser, &class_method.function);
- let method_def = ClassMethodDef {
- js_doc: method_js_doc,
- accessibility: class_method.accessibility,
- optional: class_method.is_optional,
- is_abstract: class_method.is_abstract,
- is_static: class_method.is_static,
- name: method_name,
- kind: class_method.kind,
- function_def: fn_def,
- location: doc_parser
- .ast_parser
- .get_span_location(class_method.span)
- .into(),
- };
- methods.push(method_def);
- }
- ClassProp(class_prop) => {
- let prop_js_doc = doc_parser.js_doc_for_span(class_prop.span());
-
- let ts_type = class_prop
- .type_ann
- .as_ref()
- .map(|rt| ts_type_ann_to_def(rt));
-
- let prop_name = expr_to_name(&*class_prop.key);
-
- let prop_def = ClassPropertyDef {
- js_doc: prop_js_doc,
- ts_type,
- readonly: class_prop.readonly,
- optional: class_prop.is_optional,
- is_abstract: class_prop.is_abstract,
- is_static: class_prop.is_static,
- accessibility: class_prop.accessibility,
- name: prop_name,
- location: doc_parser
- .ast_parser
- .get_span_location(class_prop.span)
- .into(),
- };
- properties.push(prop_def);
- }
- TsIndexSignature(ts_index_sig) => {
- let mut params = vec![];
- for param in &ts_index_sig.params {
- let param_def = ts_fn_param_to_param_def(param, None);
- params.push(param_def);
- }
-
- let ts_type = ts_index_sig
- .type_ann
- .as_ref()
- .map(|rt| (&*rt.type_ann).into());
-
- let index_sig_def = ClassIndexSignatureDef {
- readonly: ts_index_sig.readonly,
- params,
- ts_type,
- };
- index_signatures.push(index_sig_def);
- }
- // TODO(bartlomieju):
- PrivateMethod(_) => {}
- PrivateProp(_) => {}
- _ => {}
- }
- }
-
- let type_params =
- maybe_type_param_decl_to_type_param_defs(class.type_params.as_ref());
-
- let super_type_params = maybe_type_param_instantiation_to_type_defs(
- class.super_type_params.as_ref(),
- );
-
- ClassDef {
- is_abstract: class.is_abstract,
- extends,
- implements,
- constructors,
- properties,
- index_signatures,
- methods,
- type_params,
- super_type_params,
- }
-}
-
-pub fn get_doc_for_class_decl(
- doc_parser: &DocParser,
- class_decl: &swc_ecmascript::ast::ClassDecl,
-) -> (String, ClassDef) {
- let class_name = class_decl.ident.sym.to_string();
- let class_def = class_to_class_def(doc_parser, &class_decl.class);
-
- (class_name, class_def)
-}
diff --git a/cli/doc/display.rs b/cli/doc/display.rs
deleted file mode 100644
index 44ed62415..000000000
--- a/cli/doc/display.rs
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-use crate::colors;
-use std::fmt::{Display, Formatter, Result};
-
-pub(crate) struct Indent(pub i64);
-
-impl Display for Indent {
- fn fmt(&self, f: &mut Formatter<'_>) -> Result {
- for _ in 0..self.0 {
- write!(f, " ")?;
- }
- Ok(())
- }
-}
-
-pub(crate) struct SliceDisplayer<'a, T: Display>(&'a [T], &'a str, bool);
-
-impl<'a, T: Display> SliceDisplayer<'a, T> {
- pub fn new(
- slice: &'a [T],
- separator: &'a str,
- trailing: bool,
- ) -> SliceDisplayer<'a, T> {
- SliceDisplayer(slice, separator, trailing)
- }
-}
-
-impl<T: Display> Display for SliceDisplayer<'_, T> {
- fn fmt(&self, f: &mut Formatter<'_>) -> Result {
- if self.0.is_empty() {
- return Ok(());
- }
-
- write!(f, "{}", self.0[0])?;
- for v in &self.0[1..] {
- write!(f, "{}{}", self.1, v)?;
- }
-
- if self.2 {
- write!(f, "{}", self.1)?;
- }
-
- Ok(())
- }
-}
-
-pub(crate) fn display_abstract(is_abstract: bool) -> impl Display {
- colors::magenta(if is_abstract { "abstract " } else { "" })
-}
-
-pub(crate) fn display_accessibility(
- accessibility: Option<swc_ecmascript::ast::Accessibility>,
-) -> impl Display {
- colors::magenta(
- match accessibility.unwrap_or(swc_ecmascript::ast::Accessibility::Public) {
- swc_ecmascript::ast::Accessibility::Public => "",
- swc_ecmascript::ast::Accessibility::Protected => "protected ",
- swc_ecmascript::ast::Accessibility::Private => "private ",
- },
- )
-}
-
-pub(crate) fn display_async(is_async: bool) -> impl Display {
- colors::magenta(if is_async { "async " } else { "" })
-}
-
-pub(crate) fn display_generator(is_generator: bool) -> impl Display {
- colors::magenta(if is_generator { "*" } else { "" })
-}
-
-pub(crate) fn display_method(
- method: swc_ecmascript::ast::MethodKind,
-) -> impl Display {
- colors::magenta(match method {
- swc_ecmascript::ast::MethodKind::Getter => "get ",
- swc_ecmascript::ast::MethodKind::Setter => "set ",
- _ => "",
- })
-}
-
-pub(crate) fn display_optional(is_optional: bool) -> impl Display {
- colors::magenta(if is_optional { "?" } else { "" })
-}
-
-pub(crate) fn display_readonly(is_readonly: bool) -> impl Display {
- colors::magenta(if is_readonly { "readonly " } else { "" })
-}
-
-pub(crate) fn display_static(is_static: bool) -> impl Display {
- colors::magenta(if is_static { "static " } else { "" })
-}
diff --git a/cli/doc/enum.rs b/cli/doc/enum.rs
deleted file mode 100644
index 8161337ce..000000000
--- a/cli/doc/enum.rs
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-use serde::Serialize;
-
-use super::parser::DocParser;
-
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct EnumMemberDef {
- pub name: String,
-}
-
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct EnumDef {
- pub members: Vec<EnumMemberDef>,
-}
-
-pub fn get_doc_for_ts_enum_decl(
- _doc_parser: &DocParser,
- enum_decl: &swc_ecmascript::ast::TsEnumDecl,
-) -> (String, EnumDef) {
- let enum_name = enum_decl.id.sym.to_string();
- let mut members = vec![];
-
- for enum_member in &enum_decl.members {
- use swc_ecmascript::ast::TsEnumMemberId::*;
-
- let member_name = match &enum_member.id {
- Ident(ident) => ident.sym.to_string(),
- Str(str_) => str_.value.to_string(),
- };
-
- let member_def = EnumMemberDef { name: member_name };
- members.push(member_def);
- }
-
- let enum_def = EnumDef { members };
-
- (enum_name, enum_def)
-}
diff --git a/cli/doc/function.rs b/cli/doc/function.rs
deleted file mode 100644
index ab6430ec6..000000000
--- a/cli/doc/function.rs
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-use super::params::pat_to_param_def;
-use super::parser::DocParser;
-use super::ts_type::ts_type_ann_to_def;
-use super::ts_type::TsTypeDef;
-use super::ts_type_param::maybe_type_param_decl_to_type_param_defs;
-use super::ts_type_param::TsTypeParamDef;
-use super::ParamDef;
-use serde::Serialize;
-
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct FunctionDef {
- pub params: Vec<ParamDef>,
- pub return_type: Option<TsTypeDef>,
- pub is_async: bool,
- pub is_generator: bool,
- pub type_params: Vec<TsTypeParamDef>,
- // TODO(bartlomieju): decorators
-}
-
-pub fn function_to_function_def(
- doc_parser: &DocParser,
- function: &swc_ecmascript::ast::Function,
-) -> FunctionDef {
- let mut params = vec![];
-
- for param in &function.params {
- let param_def =
- pat_to_param_def(&param.pat, Some(&doc_parser.ast_parser.source_map));
- params.push(param_def);
- }
-
- let maybe_return_type = function
- .return_type
- .as_ref()
- .map(|rt| ts_type_ann_to_def(rt));
-
- let type_params =
- maybe_type_param_decl_to_type_param_defs(function.type_params.as_ref());
-
- FunctionDef {
- params,
- return_type: maybe_return_type,
- is_async: function.is_async,
- is_generator: function.is_generator,
- type_params,
- }
-}
-
-pub fn get_doc_for_fn_decl(
- doc_parser: &DocParser,
- fn_decl: &swc_ecmascript::ast::FnDecl,
-) -> (String, FunctionDef) {
- let name = fn_decl.ident.sym.to_string();
- let fn_def = function_to_function_def(&doc_parser, &fn_decl.function);
- (name, fn_def)
-}
diff --git a/cli/doc/interface.rs b/cli/doc/interface.rs
deleted file mode 100644
index 3c72bac23..000000000
--- a/cli/doc/interface.rs
+++ /dev/null
@@ -1,303 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-use crate::colors;
-use crate::doc::display::{display_optional, display_readonly, SliceDisplayer};
-use serde::Serialize;
-
-use super::params::ts_fn_param_to_param_def;
-use super::parser::DocParser;
-use super::ts_type::ts_type_ann_to_def;
-use super::ts_type::TsTypeDef;
-use super::ts_type_param::maybe_type_param_decl_to_type_param_defs;
-use super::ts_type_param::TsTypeParamDef;
-use super::Location;
-use super::ParamDef;
-
-use std::fmt::{Display, Formatter, Result as FmtResult};
-
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct InterfaceMethodDef {
- pub name: String,
- pub location: Location,
- pub js_doc: Option<String>,
- pub optional: bool,
- pub params: Vec<ParamDef>,
- pub return_type: Option<TsTypeDef>,
- pub type_params: Vec<TsTypeParamDef>,
-}
-
-impl Display for InterfaceMethodDef {
- fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
- write!(
- f,
- "{}{}({})",
- colors::bold(&self.name),
- display_optional(self.optional),
- SliceDisplayer::new(&self.params, ", ", false),
- )?;
- if let Some(return_type) = &self.return_type {
- write!(f, ": {}", return_type)?;
- }
- Ok(())
- }
-}
-
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct InterfacePropertyDef {
- pub name: String,
- pub location: Location,
- pub js_doc: Option<String>,
- pub params: Vec<ParamDef>,
- pub computed: bool,
- pub optional: bool,
- pub ts_type: Option<TsTypeDef>,
- pub type_params: Vec<TsTypeParamDef>,
-}
-
-impl Display for InterfacePropertyDef {
- fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
- write!(
- f,
- "{}{}",
- colors::bold(&self.name),
- display_optional(self.optional),
- )?;
- if let Some(ts_type) = &self.ts_type {
- write!(f, ": {}", ts_type)?;
- }
- Ok(())
- }
-}
-
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct InterfaceIndexSignatureDef {
- pub readonly: bool,
- pub params: Vec<ParamDef>,
- pub ts_type: Option<TsTypeDef>,
-}
-
-impl Display for InterfaceIndexSignatureDef {
- fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
- write!(
- f,
- "{}[{}]",
- display_readonly(self.readonly),
- SliceDisplayer::new(&self.params, ", ", false)
- )?;
- if let Some(ts_type) = &self.ts_type {
- write!(f, ": {}", ts_type)?;
- }
- Ok(())
- }
-}
-
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct InterfaceCallSignatureDef {
- pub location: Location,
- pub js_doc: Option<String>,
- pub params: Vec<ParamDef>,
- pub ts_type: Option<TsTypeDef>,
- pub type_params: Vec<TsTypeParamDef>,
-}
-
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct InterfaceDef {
- pub extends: Vec<TsTypeDef>,
- pub methods: Vec<InterfaceMethodDef>,
- pub properties: Vec<InterfacePropertyDef>,
- pub call_signatures: Vec<InterfaceCallSignatureDef>,
- pub index_signatures: Vec<InterfaceIndexSignatureDef>,
- pub type_params: Vec<TsTypeParamDef>,
-}
-
-pub fn expr_to_name(expr: &swc_ecmascript::ast::Expr) -> String {
- use swc_ecmascript::ast::Expr::*;
- use swc_ecmascript::ast::ExprOrSuper::*;
-
- match expr {
- Ident(ident) => ident.sym.to_string(),
- Member(member_expr) => {
- let left = match &member_expr.obj {
- Super(_) => "super".to_string(),
- Expr(boxed_expr) => expr_to_name(&*boxed_expr),
- };
- let right = expr_to_name(&*member_expr.prop);
- format!("[{}.{}]", left, right)
- }
- _ => "<TODO>".to_string(),
- }
-}
-
-pub fn get_doc_for_ts_interface_decl(
- doc_parser: &DocParser,
- interface_decl: &swc_ecmascript::ast::TsInterfaceDecl,
-) -> (String, InterfaceDef) {
- let interface_name = interface_decl.id.sym.to_string();
-
- let mut methods = vec![];
- let mut properties = vec![];
- let mut call_signatures = vec![];
- let mut index_signatures = vec![];
-
- for type_element in &interface_decl.body.body {
- use swc_ecmascript::ast::TsTypeElement::*;
-
- match &type_element {
- TsMethodSignature(ts_method_sig) => {
- let method_js_doc = doc_parser.js_doc_for_span(ts_method_sig.span);
-
- let mut params = vec![];
-
- for param in &ts_method_sig.params {
- let param_def = ts_fn_param_to_param_def(
- param,
- Some(&doc_parser.ast_parser.source_map),
- );
- params.push(param_def);
- }
-
- let name = expr_to_name(&*ts_method_sig.key);
-
- let maybe_return_type = ts_method_sig
- .type_ann
- .as_ref()
- .map(|rt| ts_type_ann_to_def(rt));
-
- let type_params = maybe_type_param_decl_to_type_param_defs(
- ts_method_sig.type_params.as_ref(),
- );
-
- let method_def = InterfaceMethodDef {
- name,
- js_doc: method_js_doc,
- location: doc_parser
- .ast_parser
- .get_span_location(ts_method_sig.span)
- .into(),
- optional: ts_method_sig.optional,
- params,
- return_type: maybe_return_type,
- type_params,
- };
- methods.push(method_def);
- }
- TsPropertySignature(ts_prop_sig) => {
- let prop_js_doc = doc_parser.js_doc_for_span(ts_prop_sig.span);
- let name = expr_to_name(&*ts_prop_sig.key);
-
- let mut params = vec![];
-
- for param in &ts_prop_sig.params {
- let param_def = ts_fn_param_to_param_def(
- param,
- Some(&doc_parser.ast_parser.source_map),
- );
- params.push(param_def);
- }
-
- let ts_type = ts_prop_sig
- .type_ann
- .as_ref()
- .map(|rt| ts_type_ann_to_def(rt));
-
- let type_params = maybe_type_param_decl_to_type_param_defs(
- ts_prop_sig.type_params.as_ref(),
- );
-
- let prop_def = InterfacePropertyDef {
- name,
- js_doc: prop_js_doc,
- location: doc_parser
- .ast_parser
- .get_span_location(ts_prop_sig.span)
- .into(),
- params,
- ts_type,
- computed: ts_prop_sig.computed,
- optional: ts_prop_sig.optional,
- type_params,
- };
- properties.push(prop_def);
- }
- TsCallSignatureDecl(ts_call_sig) => {
- let call_sig_js_doc = doc_parser.js_doc_for_span(ts_call_sig.span);
-
- let mut params = vec![];
- for param in &ts_call_sig.params {
- let param_def = ts_fn_param_to_param_def(
- param,
- Some(&doc_parser.ast_parser.source_map),
- );
- params.push(param_def);
- }
-
- let ts_type = ts_call_sig
- .type_ann
- .as_ref()
- .map(|rt| ts_type_ann_to_def(rt));
-
- let type_params = maybe_type_param_decl_to_type_param_defs(
- ts_call_sig.type_params.as_ref(),
- );
-
- let call_sig_def = InterfaceCallSignatureDef {
- js_doc: call_sig_js_doc,
- location: doc_parser
- .ast_parser
- .get_span_location(ts_call_sig.span)
- .into(),
- params,
- ts_type,
- type_params,
- };
- call_signatures.push(call_sig_def);
- }
- TsIndexSignature(ts_index_sig) => {
- let mut params = vec![];
- for param in &ts_index_sig.params {
- let param_def = ts_fn_param_to_param_def(param, None);
- params.push(param_def);
- }
-
- let ts_type = ts_index_sig
- .type_ann
- .as_ref()
- .map(|rt| (&*rt.type_ann).into());
-
- let index_sig_def = InterfaceIndexSignatureDef {
- readonly: ts_index_sig.readonly,
- params,
- ts_type,
- };
- index_signatures.push(index_sig_def);
- }
- // TODO:
- TsConstructSignatureDecl(_) => {}
- }
- }
-
- let type_params = maybe_type_param_decl_to_type_param_defs(
- interface_decl.type_params.as_ref(),
- );
-
- let extends = interface_decl
- .extends
- .iter()
- .map(|expr| expr.into())
- .collect::<Vec<TsTypeDef>>();
-
- let interface_def = InterfaceDef {
- extends,
- methods,
- properties,
- call_signatures,
- index_signatures,
- type_params,
- };
-
- (interface_name, interface_def)
-}
diff --git a/cli/doc/mod.rs b/cli/doc/mod.rs
deleted file mode 100644
index d015d9e4c..000000000
--- a/cli/doc/mod.rs
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-pub mod class;
-mod display;
-pub mod r#enum;
-pub mod function;
-pub mod interface;
-pub mod module;
-pub mod namespace;
-mod node;
-pub mod params;
-pub mod parser;
-pub mod printer;
-pub mod ts_type;
-pub mod ts_type_param;
-pub mod type_alias;
-pub mod variable;
-
-pub use node::DocNode;
-pub use node::DocNodeKind;
-pub use node::ImportDef;
-pub use node::Location;
-pub use params::ParamDef;
-pub use parser::DocParser;
-pub use printer::DocPrinter;
-
-#[cfg(test)]
-mod tests;
-
-pub fn find_nodes_by_name_recursively(
- doc_nodes: Vec<DocNode>,
- name: String,
-) -> Vec<DocNode> {
- let mut parts = name.splitn(2, '.');
- let name = parts.next();
- let leftover = parts.next();
- if name.is_none() {
- return doc_nodes;
- }
-
- let name = name.unwrap();
- let doc_nodes = find_nodes_by_name(doc_nodes, name.to_string());
-
- let mut found: Vec<DocNode> = vec![];
- match leftover {
- Some(leftover) => {
- for node in doc_nodes {
- let children = find_children_by_name(node, leftover.to_string());
- found.extend(children);
- }
- found
- }
- None => doc_nodes,
- }
-}
-
-fn find_nodes_by_name(doc_nodes: Vec<DocNode>, name: String) -> Vec<DocNode> {
- let mut found: Vec<DocNode> = vec![];
- for node in doc_nodes {
- if node.name == name {
- found.push(node);
- }
- }
- found
-}
-
-fn find_children_by_name(node: DocNode, name: String) -> Vec<DocNode> {
- match node.kind {
- DocNodeKind::Namespace => {
- let namespace_def = node.namespace_def.unwrap();
- find_nodes_by_name_recursively(namespace_def.elements, name)
- }
- // TODO(#4516) handle class, interface etc...
- _ => vec![],
- }
-}
diff --git a/cli/doc/module.rs b/cli/doc/module.rs
deleted file mode 100644
index 69effdde8..000000000
--- a/cli/doc/module.rs
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-use swc_common::Spanned;
-
-use super::parser::DocParser;
-use super::DocNode;
-
-pub fn get_doc_node_for_export_decl(
- doc_parser: &DocParser,
- export_decl: &swc_ecmascript::ast::ExportDecl,
-) -> DocNode {
- let export_span = export_decl.span();
- use swc_ecmascript::ast::Decl;
-
- let js_doc = doc_parser.js_doc_for_span(export_span);
- let location = doc_parser.ast_parser.get_span_location(export_span).into();
-
- match &export_decl.decl {
- Decl::Class(class_decl) => {
- let (name, class_def) =
- super::class::get_doc_for_class_decl(doc_parser, class_decl);
- DocNode::class(name, location, js_doc, class_def)
- }
- Decl::Fn(fn_decl) => {
- let (name, function_def) =
- super::function::get_doc_for_fn_decl(doc_parser, fn_decl);
- DocNode::function(name, location, js_doc, function_def)
- }
- Decl::Var(var_decl) => {
- let (name, var_def) = super::variable::get_doc_for_var_decl(var_decl);
- DocNode::variable(name, location, js_doc, var_def)
- }
- Decl::TsInterface(ts_interface_decl) => {
- let (name, interface_def) =
- super::interface::get_doc_for_ts_interface_decl(
- doc_parser,
- ts_interface_decl,
- );
- DocNode::interface(name, location, js_doc, interface_def)
- }
- Decl::TsTypeAlias(ts_type_alias) => {
- let (name, type_alias_def) =
- super::type_alias::get_doc_for_ts_type_alias_decl(
- doc_parser,
- ts_type_alias,
- );
- DocNode::type_alias(name, location, js_doc, type_alias_def)
- }
- Decl::TsEnum(ts_enum) => {
- let (name, enum_def) =
- super::r#enum::get_doc_for_ts_enum_decl(doc_parser, ts_enum);
- DocNode::r#enum(name, location, js_doc, enum_def)
- }
- Decl::TsModule(ts_module) => {
- let (name, namespace_def) =
- super::namespace::get_doc_for_ts_module(doc_parser, ts_module);
- DocNode::namespace(name, location, js_doc, namespace_def)
- }
- }
-}
diff --git a/cli/doc/namespace.rs b/cli/doc/namespace.rs
deleted file mode 100644
index 7bb3903ae..000000000
--- a/cli/doc/namespace.rs
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-use serde::Serialize;
-
-use super::parser::DocParser;
-use super::DocNode;
-
-#[derive(Debug, Serialize, Clone)]
-pub struct NamespaceDef {
- pub elements: Vec<DocNode>,
-}
-
-pub fn get_doc_for_ts_namespace_decl(
- doc_parser: &DocParser,
- ts_namespace_decl: &swc_ecmascript::ast::TsNamespaceDecl,
-) -> DocNode {
- let js_doc = doc_parser.js_doc_for_span(ts_namespace_decl.span);
- let location = doc_parser
- .ast_parser
- .get_span_location(ts_namespace_decl.span)
- .into();
- let namespace_name = ts_namespace_decl.id.sym.to_string();
-
- use swc_ecmascript::ast::TsNamespaceBody::*;
-
- let elements = match &*ts_namespace_decl.body {
- TsModuleBlock(ts_module_block) => {
- doc_parser.get_doc_nodes_for_module_body(ts_module_block.body.clone())
- }
- TsNamespaceDecl(ts_namespace_decl) => {
- vec![get_doc_for_ts_namespace_decl(doc_parser, ts_namespace_decl)]
- }
- };
-
- let ns_def = NamespaceDef { elements };
-
- DocNode::namespace(namespace_name, location, js_doc, ns_def)
-}
-
-pub fn get_doc_for_ts_module(
- doc_parser: &DocParser,
- ts_module_decl: &swc_ecmascript::ast::TsModuleDecl,
-) -> (String, NamespaceDef) {
- use swc_ecmascript::ast::TsModuleName;
- let namespace_name = match &ts_module_decl.id {
- TsModuleName::Ident(ident) => ident.sym.to_string(),
- TsModuleName::Str(str_) => str_.value.to_string(),
- };
-
- let elements = if let Some(body) = &ts_module_decl.body {
- use swc_ecmascript::ast::TsNamespaceBody::*;
-
- match &body {
- TsModuleBlock(ts_module_block) => {
- doc_parser.get_doc_nodes_for_module_body(ts_module_block.body.clone())
- }
- TsNamespaceDecl(ts_namespace_decl) => {
- vec![get_doc_for_ts_namespace_decl(doc_parser, ts_namespace_decl)]
- }
- }
- } else {
- vec![]
- };
-
- let ns_def = NamespaceDef { elements };
-
- (namespace_name, ns_def)
-}
diff --git a/cli/doc/node.rs b/cli/doc/node.rs
deleted file mode 100644
index 226fdc8fa..000000000
--- a/cli/doc/node.rs
+++ /dev/null
@@ -1,287 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-use serde::Serialize;
-
-#[derive(Debug, PartialEq, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub enum DocNodeKind {
- Function,
- Variable,
- Class,
- Enum,
- Interface,
- TypeAlias,
- Namespace,
- Import,
-}
-
-#[derive(Debug, Serialize, Clone, PartialEq)]
-pub struct Location {
- pub filename: String,
- pub line: usize,
- pub col: usize,
-}
-
-impl Into<Location> for swc_common::Loc {
- fn into(self) -> Location {
- use swc_common::FileName::*;
-
- let filename = match &self.file.name {
- Real(path_buf) => path_buf.to_string_lossy().to_string(),
- Custom(str_) => str_.to_string(),
- _ => panic!("invalid filename"),
- };
-
- Location {
- filename,
- line: self.line,
- col: self.col_display,
- }
- }
-}
-
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub enum ReexportKind {
- /// export * from "./path/to/module.js";
- All,
- /// export * as someNamespace from "./path/to/module.js";
- Namespace(String),
- /// export default from "./path/to/module.js";
- Default,
- /// (identifier, optional alias)
- /// export { foo } from "./path/to/module.js";
- /// export { foo as bar } from "./path/to/module.js";
- Named(String, Option<String>),
-}
-
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct Reexport {
- pub kind: ReexportKind,
- pub src: String,
-}
-
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct ModuleDoc {
- pub definitions: Vec<DocNode>,
- pub reexports: Vec<Reexport>,
-}
-
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct ImportDef {
- pub src: String,
- pub imported: Option<String>,
-}
-
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct DocNode {
- pub kind: DocNodeKind,
- pub name: String,
- pub location: Location,
- pub js_doc: Option<String>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub function_def: Option<super::function::FunctionDef>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub variable_def: Option<super::variable::VariableDef>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub enum_def: Option<super::r#enum::EnumDef>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub class_def: Option<super::class::ClassDef>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub type_alias_def: Option<super::type_alias::TypeAliasDef>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub namespace_def: Option<super::namespace::NamespaceDef>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub interface_def: Option<super::interface::InterfaceDef>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub import_def: Option<ImportDef>,
-}
-
-impl DocNode {
- pub fn function(
- name: String,
- location: Location,
- js_doc: Option<String>,
- fn_def: super::function::FunctionDef,
- ) -> Self {
- Self {
- kind: DocNodeKind::Function,
- name,
- location,
- js_doc,
- function_def: Some(fn_def),
- variable_def: None,
- enum_def: None,
- class_def: None,
- type_alias_def: None,
- namespace_def: None,
- interface_def: None,
- import_def: None,
- }
- }
-
- pub fn variable(
- name: String,
- location: Location,
- js_doc: Option<String>,
- var_def: super::variable::VariableDef,
- ) -> Self {
- Self {
- kind: DocNodeKind::Variable,
- name,
- location,
- js_doc,
- function_def: None,
- variable_def: Some(var_def),
- enum_def: None,
- class_def: None,
- type_alias_def: None,
- namespace_def: None,
- interface_def: None,
- import_def: None,
- }
- }
-
- pub fn r#enum(
- name: String,
- location: Location,
- js_doc: Option<String>,
- enum_def: super::r#enum::EnumDef,
- ) -> Self {
- Self {
- kind: DocNodeKind::Enum,
- name,
- location,
- js_doc,
- function_def: None,
- variable_def: None,
- enum_def: Some(enum_def),
- class_def: None,
- type_alias_def: None,
- namespace_def: None,
- interface_def: None,
- import_def: None,
- }
- }
-
- pub fn class(
- name: String,
- location: Location,
- js_doc: Option<String>,
- class_def: super::class::ClassDef,
- ) -> Self {
- Self {
- kind: DocNodeKind::Class,
- name,
- location,
- js_doc,
- function_def: None,
- variable_def: None,
- enum_def: None,
- class_def: Some(class_def),
- type_alias_def: None,
- namespace_def: None,
- interface_def: None,
- import_def: None,
- }
- }
-
- pub fn type_alias(
- name: String,
- location: Location,
- js_doc: Option<String>,
- type_alias_def: super::type_alias::TypeAliasDef,
- ) -> Self {
- Self {
- kind: DocNodeKind::TypeAlias,
- name,
- location,
- js_doc,
- function_def: None,
- variable_def: None,
- enum_def: None,
- class_def: None,
- type_alias_def: Some(type_alias_def),
- namespace_def: None,
- interface_def: None,
- import_def: None,
- }
- }
-
- pub fn namespace(
- name: String,
- location: Location,
- js_doc: Option<String>,
- namespace_def: super::namespace::NamespaceDef,
- ) -> Self {
- Self {
- kind: DocNodeKind::Namespace,
- name,
- location,
- js_doc,
- function_def: None,
- variable_def: None,
- enum_def: None,
- class_def: None,
- type_alias_def: None,
- namespace_def: Some(namespace_def),
- interface_def: None,
- import_def: None,
- }
- }
-
- pub fn interface(
- name: String,
- location: Location,
- js_doc: Option<String>,
- interface_def: super::interface::InterfaceDef,
- ) -> Self {
- Self {
- kind: DocNodeKind::Interface,
- name,
- location,
- js_doc,
- function_def: None,
- variable_def: None,
- enum_def: None,
- class_def: None,
- type_alias_def: None,
- namespace_def: None,
- interface_def: Some(interface_def),
- import_def: None,
- }
- }
-
- pub fn import(
- name: String,
- location: Location,
- js_doc: Option<String>,
- import_def: ImportDef,
- ) -> Self {
- Self {
- kind: DocNodeKind::Import,
- name,
- location,
- js_doc,
- function_def: None,
- variable_def: None,
- enum_def: None,
- class_def: None,
- type_alias_def: None,
- namespace_def: None,
- interface_def: None,
- import_def: Some(import_def),
- }
- }
-}
diff --git a/cli/doc/params.rs b/cli/doc/params.rs
deleted file mode 100644
index 088a4e283..000000000
--- a/cli/doc/params.rs
+++ /dev/null
@@ -1,289 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-use super::display::{display_optional, SliceDisplayer};
-use super::ts_type::{ts_type_ann_to_def, TsTypeDef};
-use serde::Serialize;
-use std::fmt::{Display, Formatter, Result as FmtResult};
-use swc_common::SourceMap;
-use swc_ecmascript::ast::{ObjectPatProp, Pat, TsFnParam};
-
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-#[serde(tag = "kind")]
-pub enum ParamDef {
- #[serde(rename_all = "camelCase")]
- Array {
- elements: Vec<Option<ParamDef>>,
- optional: bool,
- ts_type: Option<TsTypeDef>,
- },
- #[serde(rename_all = "camelCase")]
- Assign {
- left: Box<ParamDef>,
- right: String,
- ts_type: Option<TsTypeDef>,
- },
- #[serde(rename_all = "camelCase")]
- Identifier {
- name: String,
- optional: bool,
- ts_type: Option<TsTypeDef>,
- },
- #[serde(rename_all = "camelCase")]
- Object {
- props: Vec<ObjectPatPropDef>,
- optional: bool,
- ts_type: Option<TsTypeDef>,
- },
- #[serde(rename_all = "camelCase")]
- Rest {
- arg: Box<ParamDef>,
- ts_type: Option<TsTypeDef>,
- },
-}
-
-impl Display for ParamDef {
- fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
- match self {
- Self::Array {
- elements,
- optional,
- ts_type,
- } => {
- write!(f, "[")?;
- if !elements.is_empty() {
- if let Some(v) = &elements[0] {
- write!(f, "{}", v)?;
- }
- for maybe_v in &elements[1..] {
- write!(f, ", ")?;
- if let Some(v) = maybe_v {
- write!(f, "{}", v)?;
- }
- }
- }
- write!(f, "]")?;
- write!(f, "{}", display_optional(*optional))?;
- if let Some(ts_type) = ts_type {
- write!(f, ": {}", ts_type)?;
- }
- Ok(())
- }
- Self::Assign { left, ts_type, .. } => {
- write!(f, "{}", left)?;
- if let Some(ts_type) = ts_type {
- write!(f, ": {}", ts_type)?;
- }
- // TODO(SyrupThinker) As we cannot display expressions the value is just omitted
- // write!(f, " = {}", right)?;
- Ok(())
- }
- Self::Identifier {
- name,
- optional,
- ts_type,
- } => {
- write!(f, "{}{}", name, display_optional(*optional))?;
- if let Some(ts_type) = ts_type {
- write!(f, ": {}", ts_type)?;
- }
- Ok(())
- }
- Self::Object {
- props,
- optional,
- ts_type,
- } => {
- write!(
- f,
- "{{{}}}{}",
- SliceDisplayer::new(&props, ", ", false),
- display_optional(*optional)
- )?;
- if let Some(ts_type) = ts_type {
- write!(f, ": {}", ts_type)?;
- }
- Ok(())
- }
- Self::Rest { arg, ts_type } => {
- write!(f, "...{}", arg)?;
- if let Some(ts_type) = ts_type {
- write!(f, ": {}", ts_type)?;
- }
- Ok(())
- }
- }
- }
-}
-
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-#[serde(tag = "kind")]
-pub enum ObjectPatPropDef {
- Assign { key: String, value: Option<String> },
- KeyValue { key: String, value: Box<ParamDef> },
- Rest { arg: Box<ParamDef> },
-}
-
-impl Display for ObjectPatPropDef {
- fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
- match self {
- Self::KeyValue { key, .. } => {
- // The internal identifier does not need to be exposed
- write!(f, "{}", key)
- }
- Self::Assign { key, value } => {
- if let Some(_value) = value {
- // TODO(SyrupThinker) As we cannot display expressions the value is just omitted
- write!(f, "{}", key)
- } else {
- write!(f, "{}", key)
- }
- }
- Self::Rest { arg } => write!(f, "...{}", arg),
- }
- }
-}
-
-pub fn ident_to_param_def(
- ident: &swc_ecmascript::ast::Ident,
- _source_map: Option<&SourceMap>,
-) -> ParamDef {
- let ts_type = ident.type_ann.as_ref().map(|rt| ts_type_ann_to_def(rt));
-
- ParamDef::Identifier {
- name: ident.sym.to_string(),
- optional: ident.optional,
- ts_type,
- }
-}
-
-fn rest_pat_to_param_def(
- rest_pat: &swc_ecmascript::ast::RestPat,
- source_map: Option<&SourceMap>,
-) -> ParamDef {
- let ts_type = rest_pat.type_ann.as_ref().map(|rt| ts_type_ann_to_def(rt));
-
- ParamDef::Rest {
- arg: Box::new(pat_to_param_def(&*rest_pat.arg, source_map)),
- ts_type,
- }
-}
-
-fn object_pat_prop_to_def(
- object_pat_prop: &ObjectPatProp,
- source_map: Option<&SourceMap>,
-) -> ObjectPatPropDef {
- match object_pat_prop {
- ObjectPatProp::Assign(assign) => ObjectPatPropDef::Assign {
- key: assign.key.sym.to_string(),
- value: assign.value.as_ref().map(|_| "<UNIMPLEMENTED>".to_string()),
- },
- ObjectPatProp::KeyValue(keyvalue) => ObjectPatPropDef::KeyValue {
- key: prop_name_to_string(&keyvalue.key, source_map),
- value: Box::new(pat_to_param_def(&*keyvalue.value, source_map)),
- },
- ObjectPatProp::Rest(rest) => ObjectPatPropDef::Rest {
- arg: Box::new(pat_to_param_def(&*rest.arg, source_map)),
- },
- }
-}
-
-fn object_pat_to_param_def(
- object_pat: &swc_ecmascript::ast::ObjectPat,
- source_map: Option<&SourceMap>,
-) -> ParamDef {
- let props = object_pat
- .props
- .iter()
- .map(|prop| object_pat_prop_to_def(prop, source_map))
- .collect::<Vec<_>>();
- let ts_type = object_pat
- .type_ann
- .as_ref()
- .map(|rt| ts_type_ann_to_def(rt));
-
- ParamDef::Object {
- props,
- optional: object_pat.optional,
- ts_type,
- }
-}
-
-fn array_pat_to_param_def(
- array_pat: &swc_ecmascript::ast::ArrayPat,
- source_map: Option<&SourceMap>,
-) -> ParamDef {
- let elements = array_pat
- .elems
- .iter()
- .map(|elem| elem.as_ref().map(|e| pat_to_param_def(e, source_map)))
- .collect::<Vec<Option<_>>>();
- let ts_type = array_pat.type_ann.as_ref().map(|rt| ts_type_ann_to_def(rt));
-
- ParamDef::Array {
- elements,
- optional: array_pat.optional,
- ts_type,
- }
-}
-
-pub fn assign_pat_to_param_def(
- assign_pat: &swc_ecmascript::ast::AssignPat,
- source_map: Option<&SourceMap>,
-) -> ParamDef {
- let ts_type = assign_pat
- .type_ann
- .as_ref()
- .map(|rt| ts_type_ann_to_def(rt));
-
- ParamDef::Assign {
- left: Box::new(pat_to_param_def(&*assign_pat.left, source_map)),
- right: "<UNIMPLEMENTED>".to_string(),
- ts_type,
- }
-}
-
-pub fn pat_to_param_def(
- pat: &swc_ecmascript::ast::Pat,
- source_map: Option<&SourceMap>,
-) -> ParamDef {
- match pat {
- Pat::Ident(ident) => ident_to_param_def(ident, source_map),
- Pat::Array(array_pat) => array_pat_to_param_def(array_pat, source_map),
- Pat::Rest(rest_pat) => rest_pat_to_param_def(rest_pat, source_map),
- Pat::Object(object_pat) => object_pat_to_param_def(object_pat, source_map),
- Pat::Assign(assign_pat) => assign_pat_to_param_def(assign_pat, source_map),
- _ => unreachable!(),
- }
-}
-
-pub fn ts_fn_param_to_param_def(
- ts_fn_param: &swc_ecmascript::ast::TsFnParam,
- source_map: Option<&SourceMap>,
-) -> ParamDef {
- match ts_fn_param {
- TsFnParam::Ident(ident) => ident_to_param_def(ident, source_map),
- TsFnParam::Array(array_pat) => {
- array_pat_to_param_def(array_pat, source_map)
- }
- TsFnParam::Rest(rest_pat) => rest_pat_to_param_def(rest_pat, source_map),
- TsFnParam::Object(object_pat) => {
- object_pat_to_param_def(object_pat, source_map)
- }
- }
-}
-
-pub fn prop_name_to_string(
- prop_name: &swc_ecmascript::ast::PropName,
- source_map: Option<&SourceMap>,
-) -> String {
- use swc_ecmascript::ast::PropName;
- match prop_name {
- PropName::Ident(ident) => ident.sym.to_string(),
- PropName::Str(str_) => str_.value.to_string(),
- PropName::Num(num) => num.value.to_string(),
- PropName::Computed(comp_prop_name) => source_map
- .map(|sm| sm.span_to_snippet(comp_prop_name.span).unwrap())
- .unwrap_or_else(|| "<UNAVAILABLE>".to_string()),
- }
-}
diff --git a/cli/doc/parser.rs b/cli/doc/parser.rs
deleted file mode 100644
index 8950ad74b..000000000
--- a/cli/doc/parser.rs
+++ /dev/null
@@ -1,505 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-use crate::file_fetcher::map_file_extension;
-use crate::op_error::OpError;
-use crate::swc_util::AstParser;
-use swc_common::comments::CommentKind;
-use swc_common::Span;
-use swc_ecmascript::ast::Decl;
-use swc_ecmascript::ast::DefaultDecl;
-use swc_ecmascript::ast::ModuleDecl;
-use swc_ecmascript::ast::Stmt;
-
-use deno_core::ErrBox;
-use deno_core::ModuleSpecifier;
-use futures::Future;
-use regex::Regex;
-use std::collections::HashMap;
-use std::path::PathBuf;
-use std::pin::Pin;
-
-use super::namespace::NamespaceDef;
-use super::node;
-use super::node::ModuleDoc;
-use super::DocNode;
-use super::DocNodeKind;
-use super::ImportDef;
-use super::Location;
-
-pub trait DocFileLoader {
- fn resolve(
- &self,
- specifier: &str,
- referrer: &str,
- ) -> Result<ModuleSpecifier, OpError> {
- ModuleSpecifier::resolve_import(specifier, referrer).map_err(OpError::from)
- }
-
- fn load_source_code(
- &self,
- specifier: &str,
- ) -> Pin<Box<dyn Future<Output = Result<String, OpError>>>>;
-}
-
-pub struct DocParser {
- pub ast_parser: AstParser,
- pub loader: Box<dyn DocFileLoader>,
- pub private: bool,
-}
-
-impl DocParser {
- pub fn new(loader: Box<dyn DocFileLoader>, private: bool) -> Self {
- DocParser {
- loader,
- ast_parser: AstParser::default(),
- private,
- }
- }
-
- fn parse_module(
- &self,
- file_name: &str,
- source_code: &str,
- ) -> Result<ModuleDoc, ErrBox> {
- let media_type = map_file_extension(&PathBuf::from(file_name));
- let parse_result =
- self
- .ast_parser
- .parse_module(file_name, media_type, source_code);
- let module = parse_result?;
- let mut doc_entries =
- self.get_doc_nodes_for_module_body(module.body.clone());
- let import_doc_entries =
- self.get_doc_nodes_for_module_imports(module.body.clone(), file_name)?;
- doc_entries.extend(import_doc_entries);
- let reexports = self.get_reexports_for_module_body(module.body);
- let module_doc = ModuleDoc {
- definitions: doc_entries,
- reexports,
- };
- Ok(module_doc)
- }
-
- pub async fn parse(&self, file_name: &str) -> Result<Vec<DocNode>, ErrBox> {
- let source_code = self.loader.load_source_code(file_name).await?;
-
- self.parse_source(file_name, source_code.as_str())
- }
-
- pub fn parse_source(
- &self,
- file_name: &str,
- source_code: &str,
- ) -> Result<Vec<DocNode>, ErrBox> {
- let module_doc = self.parse_module(file_name, &source_code)?;
- Ok(module_doc.definitions)
- }
-
- async fn flatten_reexports(
- &self,
- reexports: &[node::Reexport],
- referrer: &str,
- ) -> Result<Vec<DocNode>, ErrBox> {
- let mut by_src: HashMap<String, Vec<node::Reexport>> = HashMap::new();
-
- let mut processed_reexports: Vec<DocNode> = vec![];
-
- for reexport in reexports {
- if by_src.get(&reexport.src).is_none() {
- by_src.insert(reexport.src.to_string(), vec![]);
- }
-
- let bucket = by_src.get_mut(&reexport.src).unwrap();
- bucket.push(reexport.clone());
- }
-
- for specifier in by_src.keys() {
- let resolved_specifier = self.loader.resolve(specifier, referrer)?;
- let doc_nodes = self.parse(&resolved_specifier.to_string()).await?;
- let reexports_for_specifier = by_src.get(specifier).unwrap();
-
- for reexport in reexports_for_specifier {
- match &reexport.kind {
- node::ReexportKind::All => {
- processed_reexports.extend(doc_nodes.clone())
- }
- node::ReexportKind::Namespace(ns_name) => {
- let ns_def = NamespaceDef {
- elements: doc_nodes.clone(),
- };
- let ns_doc_node = DocNode {
- kind: DocNodeKind::Namespace,
- name: ns_name.to_string(),
- location: Location {
- filename: specifier.to_string(),
- line: 1,
- col: 0,
- },
- js_doc: None,
- namespace_def: Some(ns_def),
- enum_def: None,
- type_alias_def: None,
- interface_def: None,
- variable_def: None,
- function_def: None,
- class_def: None,
- import_def: None,
- };
- processed_reexports.push(ns_doc_node);
- }
- node::ReexportKind::Named(ident, maybe_alias) => {
- // Try to find reexport.
- // NOTE: the reexport might actually be reexport from another
- // module; for now we're skipping nested reexports.
- let maybe_doc_node =
- doc_nodes.iter().find(|node| &node.name == ident);
-
- if let Some(doc_node) = maybe_doc_node {
- let doc_node = doc_node.clone();
- let doc_node = if let Some(alias) = maybe_alias {
- DocNode {
- name: alias.to_string(),
- ..doc_node
- }
- } else {
- doc_node
- };
-
- processed_reexports.push(doc_node);
- }
- }
- node::ReexportKind::Default => {
- // TODO: handle default export from child module
- }
- }
- }
- }
-
- Ok(processed_reexports)
- }
-
- pub async fn parse_with_reexports(
- &self,
- file_name: &str,
- ) -> Result<Vec<DocNode>, ErrBox> {
- let source_code = self.loader.load_source_code(file_name).await?;
-
- let module_doc = self.parse_module(file_name, &source_code)?;
-
- let flattened_docs = if !module_doc.reexports.is_empty() {
- let mut flattenned_reexports = self
- .flatten_reexports(&module_doc.reexports, file_name)
- .await?;
- flattenned_reexports.extend(module_doc.definitions);
- flattenned_reexports
- } else {
- module_doc.definitions
- };
-
- Ok(flattened_docs)
- }
-
- fn get_doc_nodes_for_module_imports(
- &self,
- module_body: Vec<swc_ecmascript::ast::ModuleItem>,
- referrer: &str,
- ) -> Result<Vec<DocNode>, ErrBox> {
- let mut imports = vec![];
-
- for node in module_body.iter() {
- if let swc_ecmascript::ast::ModuleItem::ModuleDecl(module_decl) = node {
- if let ModuleDecl::Import(import_decl) = module_decl {
- let (js_doc, location) = self.details_for_span(import_decl.span);
- for specifier in &import_decl.specifiers {
- use swc_ecmascript::ast::ImportSpecifier::*;
-
- let (name, maybe_imported_name, src) = match specifier {
- Named(named_specifier) => (
- named_specifier.local.sym.to_string(),
- named_specifier
- .imported
- .as_ref()
- .map(|ident| ident.sym.to_string())
- .or_else(|| Some(named_specifier.local.sym.to_string())),
- import_decl.src.value.to_string(),
- ),
- Default(default_specifier) => (
- default_specifier.local.sym.to_string(),
- Some("default".to_string()),
- import_decl.src.value.to_string(),
- ),
- Namespace(namespace_specifier) => (
- namespace_specifier.local.sym.to_string(),
- None,
- import_decl.src.value.to_string(),
- ),
- };
-
- let resolved_specifier = self.loader.resolve(&src, referrer)?;
- let import_def = ImportDef {
- src: resolved_specifier.to_string(),
- imported: maybe_imported_name,
- };
-
- let doc_node = DocNode::import(
- name,
- location.clone(),
- js_doc.clone(),
- import_def,
- );
-
- imports.push(doc_node);
- }
- }
- }
- }
-
- Ok(imports)
- }
-
- pub fn get_doc_nodes_for_module_exports(
- &self,
- module_decl: &ModuleDecl,
- ) -> Vec<DocNode> {
- match module_decl {
- ModuleDecl::ExportDecl(export_decl) => {
- vec![super::module::get_doc_node_for_export_decl(
- self,
- export_decl,
- )]
- }
- ModuleDecl::ExportDefaultDecl(export_default_decl) => {
- let (js_doc, location) =
- self.details_for_span(export_default_decl.span);
- let name = "default".to_string();
-
- let doc_node = match &export_default_decl.decl {
- DefaultDecl::Class(class_expr) => {
- let class_def =
- crate::doc::class::class_to_class_def(self, &class_expr.class);
- DocNode::class(name, location, js_doc, class_def)
- }
- DefaultDecl::Fn(fn_expr) => {
- let function_def = crate::doc::function::function_to_function_def(
- self,
- &fn_expr.function,
- );
- DocNode::function(name, location, js_doc, function_def)
- }
- DefaultDecl::TsInterfaceDecl(interface_decl) => {
- let (_, interface_def) =
- crate::doc::interface::get_doc_for_ts_interface_decl(
- self,
- interface_decl,
- );
- DocNode::interface(name, location, js_doc, interface_def)
- }
- };
-
- vec![doc_node]
- }
- ModuleDecl::ExportDefaultExpr(_export_default_expr) => vec![],
- _ => vec![],
- }
- }
-
- pub fn get_doc_node_for_stmt(&self, stmt: &Stmt) -> Option<DocNode> {
- match stmt {
- Stmt::Decl(decl) => self.get_doc_node_for_decl(decl),
- _ => None,
- }
- }
-
- fn details_for_span(&self, span: Span) -> (Option<String>, Location) {
- let js_doc = self.js_doc_for_span(span);
- let location = self.ast_parser.get_span_location(span).into();
- (js_doc, location)
- }
-
- pub fn get_doc_node_for_decl(&self, decl: &Decl) -> Option<DocNode> {
- match decl {
- Decl::Class(class_decl) => {
- if !self.private && !class_decl.declare {
- return None;
- }
- let (name, class_def) =
- super::class::get_doc_for_class_decl(self, class_decl);
- let (js_doc, location) = self.details_for_span(class_decl.class.span);
- Some(DocNode::class(name, location, js_doc, class_def))
- }
- Decl::Fn(fn_decl) => {
- if !self.private && !fn_decl.declare {
- return None;
- }
- let (name, function_def) =
- super::function::get_doc_for_fn_decl(self, fn_decl);
- let (js_doc, location) = self.details_for_span(fn_decl.function.span);
- Some(DocNode::function(name, location, js_doc, function_def))
- }
- Decl::Var(var_decl) => {
- if !self.private && !var_decl.declare {
- return None;
- }
- let (name, var_def) = super::variable::get_doc_for_var_decl(var_decl);
- let (js_doc, location) = self.details_for_span(var_decl.span);
- Some(DocNode::variable(name, location, js_doc, var_def))
- }
- Decl::TsInterface(ts_interface_decl) => {
- if !self.private && !ts_interface_decl.declare {
- return None;
- }
- let (name, interface_def) =
- super::interface::get_doc_for_ts_interface_decl(
- self,
- ts_interface_decl,
- );
- let (js_doc, location) = self.details_for_span(ts_interface_decl.span);
- Some(DocNode::interface(name, location, js_doc, interface_def))
- }
- Decl::TsTypeAlias(ts_type_alias) => {
- if !self.private && !ts_type_alias.declare {
- return None;
- }
- let (name, type_alias_def) =
- super::type_alias::get_doc_for_ts_type_alias_decl(
- self,
- ts_type_alias,
- );
- let (js_doc, location) = self.details_for_span(ts_type_alias.span);
- Some(DocNode::type_alias(name, location, js_doc, type_alias_def))
- }
- Decl::TsEnum(ts_enum) => {
- if !self.private && !ts_enum.declare {
- return None;
- }
- let (name, enum_def) =
- super::r#enum::get_doc_for_ts_enum_decl(self, ts_enum);
- let (js_doc, location) = self.details_for_span(ts_enum.span);
- Some(DocNode::r#enum(name, location, js_doc, enum_def))
- }
- Decl::TsModule(ts_module) => {
- if !self.private && !ts_module.declare {
- return None;
- }
- let (name, namespace_def) =
- super::namespace::get_doc_for_ts_module(self, ts_module);
- let (js_doc, location) = self.details_for_span(ts_module.span);
- Some(DocNode::namespace(name, location, js_doc, namespace_def))
- }
- }
- }
-
- pub fn get_reexports_for_module_body(
- &self,
- module_body: Vec<swc_ecmascript::ast::ModuleItem>,
- ) -> Vec<node::Reexport> {
- use swc_ecmascript::ast::ExportSpecifier::*;
-
- let mut reexports: Vec<node::Reexport> = vec![];
-
- for node in module_body.iter() {
- if let swc_ecmascript::ast::ModuleItem::ModuleDecl(module_decl) = node {
- let r = match module_decl {
- ModuleDecl::ExportNamed(named_export) => {
- if let Some(src) = &named_export.src {
- let src_str = src.value.to_string();
- named_export
- .specifiers
- .iter()
- .map(|export_specifier| match export_specifier {
- Namespace(ns_export) => node::Reexport {
- kind: node::ReexportKind::Namespace(
- ns_export.name.sym.to_string(),
- ),
- src: src_str.to_string(),
- },
- Default(_) => node::Reexport {
- kind: node::ReexportKind::Default,
- src: src_str.to_string(),
- },
- Named(named_export) => {
- let ident = named_export.orig.sym.to_string();
- let maybe_alias =
- named_export.exported.as_ref().map(|e| e.sym.to_string());
- let kind = node::ReexportKind::Named(ident, maybe_alias);
- node::Reexport {
- kind,
- src: src_str.to_string(),
- }
- }
- })
- .collect::<Vec<node::Reexport>>()
- } else {
- vec![]
- }
- }
- ModuleDecl::ExportAll(export_all) => {
- let reexport = node::Reexport {
- kind: node::ReexportKind::All,
- src: export_all.src.value.to_string(),
- };
- vec![reexport]
- }
- _ => vec![],
- };
-
- reexports.extend(r);
- }
- }
-
- reexports
- }
-
- pub fn get_doc_nodes_for_module_body(
- &self,
- module_body: Vec<swc_ecmascript::ast::ModuleItem>,
- ) -> Vec<DocNode> {
- let mut doc_entries: Vec<DocNode> = vec![];
- for node in module_body.iter() {
- match node {
- swc_ecmascript::ast::ModuleItem::ModuleDecl(module_decl) => {
- doc_entries
- .extend(self.get_doc_nodes_for_module_exports(module_decl));
- }
- swc_ecmascript::ast::ModuleItem::Stmt(stmt) => {
- if let Some(doc_node) = self.get_doc_node_for_stmt(stmt) {
- doc_entries.push(doc_node);
- }
- }
- }
- }
- doc_entries
- }
-
- pub fn js_doc_for_span(&self, span: Span) -> Option<String> {
- let comments = self.ast_parser.get_span_comments(span);
- let js_doc_comment = comments.iter().rev().find(|comment| {
- comment.kind == CommentKind::Block && comment.text.starts_with('*')
- })?;
-
- let mut margin_pat = String::from("");
- if let Some(margin) = self.ast_parser.source_map.span_to_margin(span) {
- for _ in 0..margin {
- margin_pat.push(' ');
- }
- }
-
- let js_doc_re = Regex::new(r#" ?\* ?"#).unwrap();
- let txt = js_doc_comment
- .text
- .split('\n')
- .map(|line| js_doc_re.replace(line, "").to_string())
- .map(|line| {
- if line.starts_with(&margin_pat) {
- line[margin_pat.len()..].to_string()
- } else {
- line
- }
- })
- .collect::<Vec<String>>()
- .join("\n");
-
- let txt = txt.trim_start().trim_end().to_string();
-
- Some(txt)
- }
-}
diff --git a/cli/doc/printer.rs b/cli/doc/printer.rs
deleted file mode 100644
index 01609d0e2..000000000
--- a/cli/doc/printer.rs
+++ /dev/null
@@ -1,426 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-
-// TODO(ry) This module builds up output by appending to a string. Instead it
-// should either use a formatting trait
-// https://doc.rust-lang.org/std/fmt/index.html#formatting-traits
-// Or perhaps implement a Serializer for serde
-// https://docs.serde.rs/serde/ser/trait.Serializer.html
-
-// TODO(ry) The methods in this module take ownership of the DocNodes, this is
-// unnecessary and can result in unnecessary copying. Instead they should take
-// references.
-
-use crate::colors;
-use crate::doc;
-use crate::doc::display::{
- display_abstract, display_async, display_generator, Indent, SliceDisplayer,
-};
-use crate::doc::DocNodeKind;
-use std::fmt::{Display, Formatter, Result as FmtResult};
-
-pub struct DocPrinter<'a> {
- doc_nodes: &'a [doc::DocNode],
- private: bool,
-}
-
-impl<'a> DocPrinter<'a> {
- pub fn new(doc_nodes: &[doc::DocNode], private: bool) -> DocPrinter {
- DocPrinter { doc_nodes, private }
- }
-
- pub fn format(&self, w: &mut Formatter<'_>) -> FmtResult {
- self.format_(w, self.doc_nodes, 0)
- }
-
- fn format_(
- &self,
- w: &mut Formatter<'_>,
- doc_nodes: &[doc::DocNode],
- indent: i64,
- ) -> FmtResult {
- let mut sorted = Vec::from(doc_nodes);
- sorted.sort_unstable_by(|a, b| {
- let kind_cmp = self.kind_order(&a.kind).cmp(&self.kind_order(&b.kind));
- if kind_cmp == core::cmp::Ordering::Equal {
- a.name.cmp(&b.name)
- } else {
- kind_cmp
- }
- });
-
- for node in &sorted {
- write!(
- w,
- "{}",
- colors::italic_gray(&format!(
- "Defined in {}:{}:{} \n\n",
- node.location.filename, node.location.line, node.location.col
- ))
- )?;
-
- self.format_signature(w, &node, indent)?;
-
- let js_doc = &node.js_doc;
- if let Some(js_doc) = js_doc {
- self.format_jsdoc(w, js_doc, indent + 1)?;
- }
- writeln!(w)?;
-
- match node.kind {
- DocNodeKind::Class => self.format_class(w, node)?,
- DocNodeKind::Enum => self.format_enum(w, node)?,
- DocNodeKind::Interface => self.format_interface(w, node)?,
- DocNodeKind::Namespace => self.format_namespace(w, node)?,
- _ => {}
- }
- }
-
- Ok(())
- }
-
- fn kind_order(&self, kind: &doc::DocNodeKind) -> i64 {
- match kind {
- DocNodeKind::Function => 0,
- DocNodeKind::Variable => 1,
- DocNodeKind::Class => 2,
- DocNodeKind::Enum => 3,
- DocNodeKind::Interface => 4,
- DocNodeKind::TypeAlias => 5,
- DocNodeKind::Namespace => 6,
- DocNodeKind::Import => 7,
- }
- }
-
- fn format_signature(
- &self,
- w: &mut Formatter<'_>,
- node: &doc::DocNode,
- indent: i64,
- ) -> FmtResult {
- match node.kind {
- DocNodeKind::Function => self.format_function_signature(w, node, indent),
- DocNodeKind::Variable => self.format_variable_signature(w, node, indent),
- DocNodeKind::Class => self.format_class_signature(w, node, indent),
- DocNodeKind::Enum => self.format_enum_signature(w, node, indent),
- DocNodeKind::Interface => {
- self.format_interface_signature(w, node, indent)
- }
- DocNodeKind::TypeAlias => {
- self.format_type_alias_signature(w, node, indent)
- }
- DocNodeKind::Namespace => {
- self.format_namespace_signature(w, node, indent)
- }
- DocNodeKind::Import => Ok(()),
- }
- }
-
- // TODO(SyrupThinker) this should use a JSDoc parser
- fn format_jsdoc(
- &self,
- w: &mut Formatter<'_>,
- jsdoc: &str,
- indent: i64,
- ) -> FmtResult {
- for line in jsdoc.lines() {
- writeln!(w, "{}{}", Indent(indent), colors::gray(&line))?;
- }
-
- Ok(())
- }
-
- fn format_class(
- &self,
- w: &mut Formatter<'_>,
- node: &doc::DocNode,
- ) -> FmtResult {
- let class_def = node.class_def.as_ref().unwrap();
- for node in &class_def.constructors {
- writeln!(w, "{}{}", Indent(1), node,)?;
- if let Some(js_doc) = &node.js_doc {
- self.format_jsdoc(w, &js_doc, 2)?;
- }
- }
- for node in class_def.properties.iter().filter(|node| {
- self.private
- || node
- .accessibility
- .unwrap_or(swc_ecmascript::ast::Accessibility::Public)
- != swc_ecmascript::ast::Accessibility::Private
- }) {
- writeln!(w, "{}{}", Indent(1), node,)?;
- if let Some(js_doc) = &node.js_doc {
- self.format_jsdoc(w, &js_doc, 2)?;
- }
- }
- for index_sign_def in &class_def.index_signatures {
- writeln!(w, "{}{}", Indent(1), index_sign_def)?;
- }
- for node in class_def.methods.iter().filter(|node| {
- self.private
- || node
- .accessibility
- .unwrap_or(swc_ecmascript::ast::Accessibility::Public)
- != swc_ecmascript::ast::Accessibility::Private
- }) {
- writeln!(w, "{}{}", Indent(1), node,)?;
- if let Some(js_doc) = &node.js_doc {
- self.format_jsdoc(w, js_doc, 2)?;
- }
- }
- writeln!(w)
- }
-
- fn format_enum(
- &self,
- w: &mut Formatter<'_>,
- node: &doc::DocNode,
- ) -> FmtResult {
- let enum_def = node.enum_def.as_ref().unwrap();
- for member in &enum_def.members {
- writeln!(w, "{}{}", Indent(1), colors::bold(&member.name))?;
- }
- writeln!(w)
- }
-
- fn format_interface(
- &self,
- w: &mut Formatter<'_>,
- node: &doc::DocNode,
- ) -> FmtResult {
- let interface_def = node.interface_def.as_ref().unwrap();
-
- for property_def in &interface_def.properties {
- writeln!(w, "{}{}", Indent(1), property_def)?;
- if let Some(js_doc) = &property_def.js_doc {
- self.format_jsdoc(w, js_doc, 2)?;
- }
- }
- for method_def in &interface_def.methods {
- writeln!(w, "{}{}", Indent(1), method_def)?;
- if let Some(js_doc) = &method_def.js_doc {
- self.format_jsdoc(w, js_doc, 2)?;
- }
- }
- for index_sign_def in &interface_def.index_signatures {
- writeln!(w, "{}{}", Indent(1), index_sign_def)?;
- }
- writeln!(w)
- }
-
- fn format_namespace(
- &self,
- w: &mut Formatter<'_>,
- node: &doc::DocNode,
- ) -> FmtResult {
- let elements = &node.namespace_def.as_ref().unwrap().elements;
- for node in elements {
- self.format_signature(w, &node, 1)?;
- if let Some(js_doc) = &node.js_doc {
- self.format_jsdoc(w, js_doc, 2)?;
- }
- }
- writeln!(w)
- }
-
- fn format_class_signature(
- &self,
- w: &mut Formatter<'_>,
- node: &doc::DocNode,
- indent: i64,
- ) -> FmtResult {
- let class_def = node.class_def.as_ref().unwrap();
- write!(
- w,
- "{}{}{} {}",
- Indent(indent),
- display_abstract(class_def.is_abstract),
- colors::magenta("class"),
- colors::bold(&node.name),
- )?;
- if !class_def.type_params.is_empty() {
- write!(
- w,
- "<{}>",
- SliceDisplayer::new(&class_def.type_params, ", ", false)
- )?;
- }
-
- if let Some(extends) = &class_def.extends {
- write!(w, " {} {}", colors::magenta("extends"), extends)?;
- }
- if !class_def.super_type_params.is_empty() {
- write!(
- w,
- "<{}>",
- SliceDisplayer::new(&class_def.super_type_params, ", ", false)
- )?;
- }
-
- if !class_def.implements.is_empty() {
- write!(
- w,
- " {} {}",
- colors::magenta("implements"),
- SliceDisplayer::new(&class_def.implements, ", ", false)
- )?;
- }
-
- writeln!(w)
- }
-
- fn format_enum_signature(
- &self,
- w: &mut Formatter<'_>,
- node: &doc::DocNode,
- indent: i64,
- ) -> FmtResult {
- writeln!(
- w,
- "{}{} {}",
- Indent(indent),
- colors::magenta("enum"),
- colors::bold(&node.name)
- )
- }
-
- fn format_function_signature(
- &self,
- w: &mut Formatter<'_>,
- node: &doc::DocNode,
- indent: i64,
- ) -> FmtResult {
- let function_def = node.function_def.as_ref().unwrap();
- write!(
- w,
- "{}{}{}{} {}",
- Indent(indent),
- display_async(function_def.is_async),
- colors::magenta("function"),
- display_generator(function_def.is_generator),
- colors::bold(&node.name)
- )?;
- if !function_def.type_params.is_empty() {
- write!(
- w,
- "<{}>",
- SliceDisplayer::new(&function_def.type_params, ", ", false)
- )?;
- }
- write!(
- w,
- "({})",
- SliceDisplayer::new(&function_def.params, ", ", false)
- )?;
- if let Some(return_type) = &function_def.return_type {
- write!(w, ": {}", return_type)?;
- }
- writeln!(w)
- }
-
- fn format_interface_signature(
- &self,
- w: &mut Formatter<'_>,
- node: &doc::DocNode,
- indent: i64,
- ) -> FmtResult {
- let interface_def = node.interface_def.as_ref().unwrap();
- write!(
- w,
- "{}{} {}",
- Indent(indent),
- colors::magenta("interface"),
- colors::bold(&node.name)
- )?;
-
- if !interface_def.type_params.is_empty() {
- write!(
- w,
- "<{}>",
- SliceDisplayer::new(&interface_def.type_params, ", ", false)
- )?;
- }
-
- if !interface_def.extends.is_empty() {
- write!(
- w,
- " {} {}",
- colors::magenta("extends"),
- SliceDisplayer::new(&interface_def.extends, ", ", false)
- )?;
- }
-
- writeln!(w)
- }
-
- fn format_type_alias_signature(
- &self,
- w: &mut Formatter<'_>,
- node: &doc::DocNode,
- indent: i64,
- ) -> FmtResult {
- let type_alias_def = node.type_alias_def.as_ref().unwrap();
- write!(
- w,
- "{}{} {}",
- Indent(indent),
- colors::magenta("type"),
- colors::bold(&node.name),
- )?;
-
- if !type_alias_def.type_params.is_empty() {
- write!(
- w,
- "<{}>",
- SliceDisplayer::new(&type_alias_def.type_params, ", ", false)
- )?;
- }
-
- writeln!(w, " = {}", type_alias_def.ts_type)
- }
-
- fn format_namespace_signature(
- &self,
- w: &mut Formatter<'_>,
- node: &doc::DocNode,
- indent: i64,
- ) -> FmtResult {
- writeln!(
- w,
- "{}{} {}",
- Indent(indent),
- colors::magenta("namespace"),
- colors::bold(&node.name)
- )
- }
-
- fn format_variable_signature(
- &self,
- w: &mut Formatter<'_>,
- node: &doc::DocNode,
- indent: i64,
- ) -> FmtResult {
- let variable_def = node.variable_def.as_ref().unwrap();
- write!(
- w,
- "{}{} {}",
- Indent(indent),
- colors::magenta(match variable_def.kind {
- swc_ecmascript::ast::VarDeclKind::Const => "const",
- swc_ecmascript::ast::VarDeclKind::Let => "let",
- swc_ecmascript::ast::VarDeclKind::Var => "var",
- }),
- colors::bold(&node.name),
- )?;
- if let Some(ts_type) = &variable_def.ts_type {
- write!(w, ": {}", ts_type)?;
- }
- writeln!(w)
- }
-}
-
-impl<'a> Display for DocPrinter<'a> {
- fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
- self.format(f)
- }
-}
diff --git a/cli/doc/tests.rs b/cli/doc/tests.rs
deleted file mode 100644
index 2faf617cc..000000000
--- a/cli/doc/tests.rs
+++ /dev/null
@@ -1,2002 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-use super::DocParser;
-use super::DocPrinter;
-use crate::colors;
-use serde_json::json;
-
-use super::parser::DocFileLoader;
-use crate::op_error::OpError;
-use std::collections::HashMap;
-
-use futures::Future;
-use futures::FutureExt;
-use std::pin::Pin;
-
-pub struct TestLoader {
- files: HashMap<String, String>,
-}
-
-impl TestLoader {
- pub fn new(files_vec: Vec<(String, String)>) -> Box<Self> {
- let mut files = HashMap::new();
-
- for file_tuple in files_vec {
- files.insert(file_tuple.0, file_tuple.1);
- }
-
- Box::new(Self { files })
- }
-}
-
-impl DocFileLoader for TestLoader {
- fn load_source_code(
- &self,
- specifier: &str,
- ) -> Pin<Box<dyn Future<Output = Result<String, OpError>>>> {
- let res = match self.files.get(specifier) {
- Some(source_code) => Ok(source_code.to_string()),
- None => Err(OpError::other("not found".to_string())),
- };
-
- async move { res }.boxed_local()
- }
-}
-
-macro_rules! doc_test {
- ( $name:ident, $source:expr; $block:block ) => {
- doc_test!($name, $source, false; $block);
- };
-
- ( $name:ident, $source:expr, private; $block:block ) => {
- doc_test!($name, $source, true; $block);
- };
-
- ( $name:ident, $source:expr, $private:expr; $block:block ) => {
- #[tokio::test]
- async fn $name() {
- let source_code = $source;
- let private = $private;
-
- let loader =
- TestLoader::new(vec![("test.ts".to_string(), source_code.to_string())]);
- let entries = DocParser::new(loader, private)
- .parse("test.ts")
- .await
- .unwrap();
-
- let doc = DocPrinter::new(&entries, private).to_string();
- #[allow(unused_variables)]
- let doc = colors::strip_ansi_codes(&doc);
-
- $block
- }
- };
-}
-
-macro_rules! contains_test {
- ( $name:ident, $source:expr;
- $( $contains:expr ),* $( ; $( $notcontains:expr ),* )? ) => {
- contains_test!($name, $source, false; $($contains),* $(;$($notcontains),*)?);
- };
-
- ( $name:ident, $source:expr, private;
- $( $contains:expr ),* $( ; $( $notcontains:expr ),* )? ) => {
- contains_test!($name, $source, true; $($contains),* $(;$($notcontains),*)?);
- };
-
- ( $name:ident, $source:expr, $private:expr;
- $( $contains:expr ),* $( ; $( $notcontains:expr ),* )? ) => {
- doc_test!($name, $source, $private; {
- $(
- assert!(doc.contains($contains));
- )*
- $(
- $(
- assert!(!doc.contains($notcontains));
- )*
- )?
- });
- };
-}
-
-macro_rules! json_test {
- ( $name:ident, $source:expr; $json:tt ) => {
- json_test!($name, $source, false; $json);
- };
-
- ( $name:ident, $source:expr, private; $json:tt ) => {
- json_test!($name, $source, true; $json);
- };
-
- ( $name:ident, $source:expr, $private:expr; $json:tt ) => {
- doc_test!($name, $source, $private; {
- let actual = serde_json::to_value(&entries).unwrap();
- let expected_json = json!($json);
- assert_eq!(actual, expected_json);
- });
- };
-}
-
-#[tokio::test]
-async fn reexports() {
- let nested_reexport_source_code = r#"
-/**
- * JSDoc for bar
- */
-export const bar = "bar";
-
-export default 42;
-"#;
- let reexport_source_code = r#"
-import { bar } from "./nested_reexport.ts";
-
-/**
- * JSDoc for const
- */
-export const foo = "foo";
-
-export const fizz = "fizz";
-"#;
- let test_source_code = r#"
-export { default, foo as fooConst } from "./reexport.ts";
-import { fizz as buzz } from "./reexport.ts";
-
-/** JSDoc for function */
-export function fooFn(a: number) {
- return a;
-}
-"#;
- let loader = TestLoader::new(vec![
- ("file:///test.ts".to_string(), test_source_code.to_string()),
- (
- "file:///reexport.ts".to_string(),
- reexport_source_code.to_string(),
- ),
- (
- "file:///nested_reexport.ts".to_string(),
- nested_reexport_source_code.to_string(),
- ),
- ]);
- let entries = DocParser::new(loader, false)
- .parse_with_reexports("file:///test.ts")
- .await
- .unwrap();
- assert_eq!(entries.len(), 3);
-
- let expected_json = json!([
- {
- "kind": "variable",
- "name": "fooConst",
- "location": {
- "filename": "file:///reexport.ts",
- "line": 7,
- "col": 0
- },
- "jsDoc": "JSDoc for const",
- "variableDef": {
- "tsType": null,
- "kind": "const"
- }
- },
- {
- "kind": "function",
- "name": "fooFn",
- "location": {
- "filename": "file:///test.ts",
- "line": 6,
- "col": 0
- },
- "jsDoc": "JSDoc for function",
- "functionDef": {
- "params": [
- {
- "name": "a",
- "kind": "identifier",
- "optional": false,
- "tsType": {
- "keyword": "number",
- "kind": "keyword",
- "repr": "number",
- },
- }
- ],
- "typeParams": [],
- "returnType": null,
- "isAsync": false,
- "isGenerator": false
- },
- },
- {
- "kind": "import",
- "name": "buzz",
- "location": {
- "filename": "file:///test.ts",
- "line": 3,
- "col": 0
- },
- "jsDoc": null,
- "importDef": {
- "src": "file:///reexport.ts",
- "imported": "fizz",
- }
- }
- ]);
- let actual = serde_json::to_value(&entries).unwrap();
- assert_eq!(actual, expected_json);
-
- assert!(colors::strip_ansi_codes(
- DocPrinter::new(&entries, false).to_string().as_str()
- )
- .contains("function fooFn(a: number)"));
-}
-
-#[tokio::test]
-async fn filter_nodes_by_name() {
- use super::find_nodes_by_name_recursively;
- let source_code = r#"
-export namespace Deno {
- export class Buffer {}
- export function test(options: object): void;
- export function test(name: string, fn: Function): void;
- export function test(name: string | object, fn?: Function): void {}
-}
-
-export namespace Deno {
- export namespace Inner {
- export function a(): void {}
- export const b = 100;
- }
-}
-"#;
- let loader =
- TestLoader::new(vec![("test.ts".to_string(), source_code.to_string())]);
- let entries = DocParser::new(loader, false)
- .parse("test.ts")
- .await
- .unwrap();
-
- let found =
- find_nodes_by_name_recursively(entries.clone(), "Deno".to_string());
- assert_eq!(found.len(), 2);
- assert_eq!(found[0].name, "Deno".to_string());
- assert_eq!(found[1].name, "Deno".to_string());
-
- let found =
- find_nodes_by_name_recursively(entries.clone(), "Deno.test".to_string());
- assert_eq!(found.len(), 3);
- assert_eq!(found[0].name, "test".to_string());
- assert_eq!(found[1].name, "test".to_string());
- assert_eq!(found[2].name, "test".to_string());
-
- let found =
- find_nodes_by_name_recursively(entries.clone(), "Deno.Inner.a".to_string());
- assert_eq!(found.len(), 1);
- assert_eq!(found[0].name, "a".to_string());
-
- let found =
- find_nodes_by_name_recursively(entries.clone(), "Deno.test.a".to_string());
- assert_eq!(found.len(), 0);
-
- let found = find_nodes_by_name_recursively(entries, "a.b.c".to_string());
- assert_eq!(found.len(), 0);
-}
-
-mod serialization {
- use super::*;
-
- json_test!(declare_namespace,
- r#"
-/** Namespace JSdoc */
-declare namespace RootNs {
- declare const a = "a";
-
- /** Nested namespace JSDoc */
- declare namespace NestedNs {
- declare enum Foo {
- a = 1,
- b = 2,
- c = 3,
- }
- }
-}
- "#;
- [{
- "kind": "namespace",
- "name": "RootNs",
- "location": {
- "filename": "test.ts",
- "line": 3,
- "col": 0
- },
- "jsDoc": "Namespace JSdoc",
- "namespaceDef": {
- "elements": [
- {
- "kind": "variable",
- "name": "a",
- "location": {
- "filename": "test.ts",
- "line": 4,
- "col": 12
- },
- "jsDoc": null,
- "variableDef": {
- "tsType": null,
- "kind": "const"
- }
- },
- {
- "kind": "namespace",
- "name": "NestedNs",
- "location": {
- "filename": "test.ts",
- "line": 7,
- "col": 4
- },
- "jsDoc": "Nested namespace JSDoc",
- "namespaceDef": {
- "elements": [
- {
- "kind": "enum",
- "name": "Foo",
- "location": {
- "filename": "test.ts",
- "line": 8,
- "col": 6
- },
- "jsDoc": null,
- "enumDef": {
- "members": [
- {
- "name": "a"
- },
- {
- "name": "b"
- },
- {
- "name": "c"
- }
- ]
- }
- }
- ]
- }
- }
- ]
- }
- }]);
-
- json_test!(export_class,
- r#"
-/** Class doc */
-export class Foobar extends Fizz implements Buzz, Aldrin {
- private private1?: boolean;
- protected protected1: number;
- public public1: boolean;
- public2: number;
-
- /** Constructor js doc */
- constructor(name: string, private private2: number, protected protected2: number) {}
-
- /** Async foo method */
- async foo(): Promise<void> {
- //
- }
-
- /** Sync bar method */
- bar?(): void {
- //
- }
-}
- "#;
- [{
- "kind": "class",
- "name": "Foobar",
- "location": {
- "filename": "test.ts",
- "line": 3,
- "col": 0
- },
- "jsDoc": "Class doc",
- "classDef": {
- "isAbstract": false,
- "extends": "Fizz",
- "implements": [
- {
- "repr": "Buzz",
- "kind": "typeRef",
- "typeRef": {
- "typeParams": null,
- "typeName": "Buzz"
- }
- },
- {
- "repr": "Aldrin",
- "kind": "typeRef",
- "typeRef": {
- "typeParams": null,
- "typeName": "Aldrin"
- }
- }
- ],
- "typeParams": [],
- "superTypeParams": [],
- "constructors": [
- {
- "jsDoc": "Constructor js doc",
- "accessibility": null,
- "name": "constructor",
- "params": [
- {
- "name": "name",
- "kind": "identifier",
- "optional": false,
- "tsType": {
- "repr": "string",
- "kind": "keyword",
- "keyword": "string"
- }
- },
- {
- "name": "private2",
- "kind": "identifier",
- "optional": false,
- "tsType": {
- "repr": "number",
- "kind": "keyword",
- "keyword": "number"
- }
- },
- {
- "name": "protected2",
- "kind": "identifier",
- "optional": false,
- "tsType": {
- "repr": "number",
- "kind": "keyword",
- "keyword": "number"
- }
- }
- ],
- "location": {
- "filename": "test.ts",
- "line": 10,
- "col": 4
- }
- }
- ],
- "properties": [
- {
- "jsDoc": null,
- "tsType": {
- "repr": "boolean",
- "kind": "keyword",
- "keyword": "boolean"
- },
- "readonly": false,
- "accessibility": "private",
- "optional": true,
- "isAbstract": false,
- "isStatic": false,
- "name": "private1",
- "location": {
- "filename": "test.ts",
- "line": 4,
- "col": 4
- }
- },
- {
- "jsDoc": null,
- "tsType": {
- "repr": "number",
- "kind": "keyword",
- "keyword": "number"
- },
- "readonly": false,
- "accessibility": "protected",
- "optional": false,
- "isAbstract": false,
- "isStatic": false,
- "name": "protected1",
- "location": {
- "filename": "test.ts",
- "line": 5,
- "col": 4
- }
- },
- {
- "jsDoc": null,
- "tsType": {
- "repr": "boolean",
- "kind": "keyword",
- "keyword": "boolean"
- },
- "readonly": false,
- "accessibility": "public",
- "optional": false,
- "isAbstract": false,
- "isStatic": false,
- "name": "public1",
- "location": {
- "filename": "test.ts",
- "line": 6,
- "col": 4
- }
- },
- {
- "jsDoc": null,
- "tsType": {
- "repr": "number",
- "kind": "keyword",
- "keyword": "number"
- },
- "readonly": false,
- "accessibility": null,
- "optional": false,
- "isAbstract": false,
- "isStatic": false,
- "name": "public2",
- "location": {
- "filename": "test.ts",
- "line": 7,
- "col": 4
- }
- }
- ],
- "indexSignatures": [],
- "methods": [
- {
- "jsDoc": "Async foo method",
- "accessibility": null,
- "optional": false,
- "isAbstract": false,
- "isStatic": false,
- "name": "foo",
- "kind": "method",
- "functionDef": {
- "params": [],
- "returnType": {
- "repr": "Promise",
- "kind": "typeRef",
- "typeRef": {
- "typeParams": [
- {
- "repr": "void",
- "kind": "keyword",
- "keyword": "void"
- }
- ],
- "typeName": "Promise"
- }
- },
- "typeParams": [],
- "isAsync": true,
- "isGenerator": false
- },
- "location": {
- "filename": "test.ts",
- "line": 13,
- "col": 4
- }
- },
- {
- "jsDoc": "Sync bar method",
- "accessibility": null,
- "optional": true,
- "isAbstract": false,
- "isStatic": false,
- "name": "bar",
- "kind": "method",
- "functionDef": {
- "params": [],
- "returnType": {
- "repr": "void",
- "kind": "keyword",
- "keyword": "void"
- },
- "isAsync": false,
- "isGenerator": false,
- "typeParams": []
- },
- "location": {
- "filename": "test.ts",
- "line": 18,
- "col": 4
- }
- }
- ]
- }
- }]);
-
- json_test!(export_const,
- r#"
-/** Something about fizzBuzz */
-export const fizzBuzz = "fizzBuzz";
-
-export const env: {
- /** get doc */
- get(key: string): string | undefined;
-
- /** set doc */
- set(key: string, value: string): void;
-}
- "#;
- [
- {
- "kind":"variable",
- "name":"fizzBuzz",
- "location":{
- "filename":"test.ts",
- "line":3,
- "col":0
- },
- "jsDoc":"Something about fizzBuzz",
- "variableDef":{
- "tsType":null,
- "kind":"const"
- }
- },
- {
- "kind":"variable",
- "name":"env",
- "location":{
- "filename":"test.ts",
- "line":5,
- "col":0
- },
- "jsDoc":null,
- "variableDef":{
- "tsType":{
- "repr":"",
- "kind":"typeLiteral",
- "typeLiteral":{
- "methods":[{
- "name":"get",
- "params":[
- {
- "name":"key",
- "kind":"identifier",
- "optional":false,
- "tsType":{
- "repr":"string",
- "kind":"keyword",
- "keyword":"string"
- }
- }
- ],
- "returnType":{
- "repr":"",
- "kind":"union",
- "union":[
- {
- "repr":"string",
- "kind":"keyword",
- "keyword":"string"
- },
- {
- "repr":"undefined",
- "kind":"keyword",
- "keyword":"undefined"
- }
- ]
- },
- "typeParams":[]
- }, {
- "name":"set",
- "params":[
- {
- "name":"key",
- "kind":"identifier",
- "optional":false,
- "tsType":{
- "repr":"string",
- "kind":"keyword",
- "keyword":"string"
- }
- },
- {
- "name":"value",
- "kind":"identifier",
- "optional":false,
- "tsType":{
- "repr":"string",
- "kind":"keyword",
- "keyword":"string"
- }
- }
- ],
- "returnType":{
- "repr":"void",
- "kind":"keyword",
- "keyword":"void"
- },
- "typeParams":[]
- }
- ],
- "properties":[],
- "callSignatures":[],
- "indexSignatures": []
- }
- },
- "kind":"const"
- }
- }
- ]
- );
-
- json_test!(export_default_class,
- r#"
-/** Class doc */
-export default class Foobar {
- /** Constructor js doc */
- constructor(name: string, private private2: number, protected protected2: number) {}
-}
- "#;
- [{
- "kind": "class",
- "name": "default",
- "location": {
- "filename": "test.ts",
- "line": 3,
- "col": 0
- },
- "jsDoc": "Class doc",
- "classDef": {
- "isAbstract": false,
- "extends": null,
- "implements": [],
- "typeParams": [],
- "superTypeParams": [],
- "constructors": [
- {
- "jsDoc": "Constructor js doc",
- "accessibility": null,
- "name": "constructor",
- "params": [
- {
- "name": "name",
- "kind": "identifier",
- "optional": false,
- "tsType": {
- "repr": "string",
- "kind": "keyword",
- "keyword": "string"
- }
- },
- {
- "name": "private2",
- "kind": "identifier",
- "optional": false,
- "tsType": {
- "repr": "number",
- "kind": "keyword",
- "keyword": "number"
- }
- },
- {
- "name": "protected2",
- "kind": "identifier",
- "optional": false,
- "tsType": {
- "repr": "number",
- "kind": "keyword",
- "keyword": "number"
- }
- }
- ],
- "location": {
- "filename": "test.ts",
- "line": 5,
- "col": 4
- }
- }
- ],
- "properties": [],
- "indexSignatures": [],
- "methods": []
- }
- }]);
-
- json_test!(export_default_fn,
- r#"
-export default function foo(a: number) {
- return a;
-}
- "#;
- [{
- "kind": "function",
- "name": "default",
- "location": {
- "filename": "test.ts",
- "line": 2,
- "col": 15
- },
- "jsDoc": null,
- "functionDef": {
- "params": [
- {
- "name": "a",
- "kind": "identifier",
- "optional": false,
- "tsType": {
- "keyword": "number",
- "kind": "keyword",
- "repr": "number",
- },
- }
- ],
- "typeParams": [],
- "returnType": null,
- "isAsync": false,
- "isGenerator": false
- }
- }]);
-
- json_test!(export_default_interface,
- r#"
-/**
- * Interface js doc
- */
-export default interface Reader {
- /** Read n bytes */
- read?(buf: Uint8Array, something: unknown): Promise<number>
-}
- "#;
- [{
- "kind": "interface",
- "name": "default",
- "location": {
- "filename": "test.ts",
- "line": 5,
- "col": 0
- },
- "jsDoc": "Interface js doc",
- "interfaceDef": {
- "extends": [],
- "methods": [
- {
- "name": "read",
- "location": {
- "filename": "test.ts",
- "line": 7,
- "col": 4
- },
- "optional": true,
- "jsDoc": "Read n bytes",
- "params": [
- {
- "name": "buf",
- "kind": "identifier",
- "optional": false,
- "tsType": {
- "repr": "Uint8Array",
- "kind": "typeRef",
- "typeRef": {
- "typeParams": null,
- "typeName": "Uint8Array"
- }
- }
- },
- {
- "name": "something",
- "kind": "identifier",
- "optional": false,
- "tsType": {
- "repr": "unknown",
- "kind": "keyword",
- "keyword": "unknown"
- }
- }
- ],
- "typeParams": [],
- "returnType": {
- "repr": "Promise",
- "kind": "typeRef",
- "typeRef": {
- "typeParams": [
- {
- "repr": "number",
- "kind": "keyword",
- "keyword": "number"
- }
- ],
- "typeName": "Promise"
- }
- }
- }
- ],
- "properties": [],
- "callSignatures": [],
- "indexSignatures": [],
- "typeParams": []
- }
- }]);
-
- json_test!(export_enum,
- r#"
-/**
- * Some enum for good measure
- */
-export enum Hello {
- World = "world",
- Fizz = "fizz",
- Buzz = "buzz",
-}
- "#;
- [{
- "kind": "enum",
- "name": "Hello",
- "location": {
- "filename": "test.ts",
- "line": 5,
- "col": 0
- },
- "jsDoc": "Some enum for good measure",
- "enumDef": {
- "members": [
- {
- "name": "World"
- },
- {
- "name": "Fizz"
- },
- {
- "name": "Buzz"
- }
- ]
- }
- }]);
-
- json_test!(export_fn,
- r#"/**
-* @module foo
-*/
-
-/**
-* Hello there, this is a multiline JSdoc.
-*
-* It has many lines
-*
-* Or not that many?
-*/
-export function foo(a: string, b?: number, cb: (...cbArgs: unknown[]) => void, ...args: unknown[]): void {
- /**
- * @todo document all the things.
- */
- console.log("Hello world");
-}
- "#;
- [{
- "functionDef": {
- "isAsync": false,
- "isGenerator": false,
- "typeParams": [],
- "params": [
- {
- "name": "a",
- "kind": "identifier",
- "optional": false,
- "tsType": {
- "keyword": "string",
- "kind": "keyword",
- "repr": "string",
- },
- },
- {
- "name": "b",
- "kind": "identifier",
- "optional": true,
- "tsType": {
- "keyword": "number",
- "kind": "keyword",
- "repr": "number",
- },
- },
- {
- "name": "cb",
- "kind": "identifier",
- "optional": false,
- "tsType": {
- "repr": "",
- "kind": "fnOrConstructor",
- "fnOrConstructor": {
- "constructor": false,
- "tsType": {
- "keyword": "void",
- "kind": "keyword",
- "repr": "void"
- },
- "typeParams": [],
- "params": [{
- "arg": {
- "name": "cbArgs",
- "kind": "identifier",
- "optional": false,
- "tsType": null
- },
- "kind": "rest",
- "tsType": {
- "repr": "",
- "kind": "array",
- "array": {
- "repr": "unknown",
- "kind": "keyword",
- "keyword": "unknown"
- }
- },
- }]
- }
- },
- },
- {
- "arg": {
- "name": "args",
- "kind": "identifier",
- "optional": false,
- "tsType": null
- },
- "kind": "rest",
- "tsType": {
- "array": {
- "keyword": "unknown",
- "kind": "keyword",
- "repr": "unknown"
- },
- "kind": "array",
- "repr": ""
- }
- }
- ],
- "returnType": {
- "keyword": "void",
- "kind": "keyword",
- "repr": "void",
- },
- },
- "jsDoc": "Hello there, this is a multiline JSdoc.\n\nIt has many lines\n\nOr not that many?",
- "kind": "function",
- "location": {
- "col": 0,
- "filename": "test.ts",
- "line": 12,
- },
- "name": "foo",
- }]);
-
- json_test!(export_fn2,
- r#"
-interface AssignOpts {
- a: string;
- b: number;
-}
-
-export function foo([e,,f, ...g]: number[], { c, d: asdf, i = "asdf", ...rest}, ops: AssignOpts = {}): void {
- console.log("Hello world");
-}
- "#;
- [{
- "functionDef": {
- "isAsync": false,
- "isGenerator": false,
- "typeParams": [],
- "params": [
- {
- "elements": [
- {
- "name": "e",
- "kind": "identifier",
- "optional": false,
- "tsType": null
- },
- null,
- {
- "name": "f",
- "kind": "identifier",
- "optional": false,
- "tsType": null
- },
- {
- "arg": {
- "name": "g",
- "kind": "identifier",
- "optional": false,
- "tsType": null
- },
- "kind": "rest",
- "tsType": null
- }
- ],
- "kind": "array",
- "optional": false,
- "tsType": {
- "repr": "",
- "kind": "array",
- "array": {
- "repr": "number",
- "kind": "keyword",
- "keyword": "number"
- }
- }
- },
- {
- "kind": "object",
- "optional": false,
- "props": [
- {
- "kind": "assign",
- "key": "c",
- "value": null
- },
- {
- "kind": "keyValue",
- "key": "d",
- "value": {
- "name": "asdf",
- "kind": "identifier",
- "optional": false,
- "tsType": null
- }
- },
- {
- "kind": "assign",
- "key": "i",
- "value": "<UNIMPLEMENTED>"
- },
- {
- "arg": {
- "name": "rest",
- "kind": "identifier",
- "optional": false,
- "tsType": null
- },
- "kind": "rest"
- }
- ],
- "tsType": null
- },
- {
- "kind": "assign",
- "left": {
- "name": "ops",
- "kind": "identifier",
- "optional": false,
- "tsType": {
- "repr": "AssignOpts",
- "kind": "typeRef",
- "typeRef": {
- "typeName": "AssignOpts",
- "typeParams": null,
- }
- }
- },
- "right": "<UNIMPLEMENTED>",
- "tsType": null
- }
- ],
- "returnType": {
- "keyword": "void",
- "kind": "keyword",
- "repr": "void",
- },
- },
- "jsDoc": null,
- "kind": "function",
- "location": {
- "col": 0,
- "filename": "test.ts",
- "line": 7,
- },
- "name": "foo",
- }]);
-
- json_test!(export_interface,
- r#"
-interface Foo {
- foo(): void;
-}
-interface Bar {
- bar(): void;
-}
-/**
- * Interface js doc
- */
-export interface Reader extends Foo, Bar {
- /** Read n bytes */
- read?(buf: Uint8Array, something: unknown): Promise<number>
-}
- "#;
- [{
- "kind": "interface",
- "name": "Reader",
- "location": {
- "filename": "test.ts",
- "line": 11,
- "col": 0
- },
- "jsDoc": "Interface js doc",
- "interfaceDef": {
- "extends": [
- {
- "repr": "Foo",
- "kind": "typeRef",
- "typeRef": {
- "typeParams": null,
- "typeName": "Foo"
- }
- },
- {
- "repr": "Bar",
- "kind": "typeRef",
- "typeRef": {
- "typeParams": null,
- "typeName": "Bar"
- }
- }
- ],
- "methods": [
- {
- "name": "read",
- "location": {
- "filename": "test.ts",
- "line": 13,
- "col": 4
- },
- "optional": true,
- "jsDoc": "Read n bytes",
- "params": [
- {
- "name": "buf",
- "kind": "identifier",
- "optional": false,
- "tsType": {
- "repr": "Uint8Array",
- "kind": "typeRef",
- "typeRef": {
- "typeParams": null,
- "typeName": "Uint8Array"
- }
- }
- },
- {
- "name": "something",
- "kind": "identifier",
- "optional": false,
- "tsType": {
- "repr": "unknown",
- "kind": "keyword",
- "keyword": "unknown"
- }
- }
- ],
- "typeParams": [],
- "returnType": {
- "repr": "Promise",
- "kind": "typeRef",
- "typeRef": {
- "typeParams": [
- {
- "repr": "number",
- "kind": "keyword",
- "keyword": "number"
- }
- ],
- "typeName": "Promise"
- }
- }
- }
- ],
- "properties": [],
- "callSignatures": [],
- "indexSignatures": [],
- "typeParams": [],
- }
- }]);
-
- json_test!(export_interface2,
- r#"
-export interface TypedIface<T> {
- something(): T
-}
- "#;
- [{
- "kind": "interface",
- "name": "TypedIface",
- "location": {
- "filename": "test.ts",
- "line": 2,
- "col": 0
- },
- "jsDoc": null,
- "interfaceDef": {
- "extends": [],
- "methods": [
- {
- "name": "something",
- "location": {
- "filename": "test.ts",
- "line": 3,
- "col": 4
- },
- "jsDoc": null,
- "optional": false,
- "params": [],
- "typeParams": [],
- "returnType": {
- "repr": "T",
- "kind": "typeRef",
- "typeRef": {
- "typeParams": null,
- "typeName": "T"
- }
- }
- }
- ],
- "properties": [],
- "callSignatures": [],
- "indexSignatures": [],
- "typeParams": [
- { "name": "T" }
- ],
- }
- }]);
-
- json_test!(export_type_alias,
- r#"
-/** Array holding numbers */
-export type NumberArray = Array<number>;
- "#;
- [{
- "kind": "typeAlias",
- "name": "NumberArray",
- "location": {
- "filename": "test.ts",
- "line": 3,
- "col": 0
- },
- "jsDoc": "Array holding numbers",
- "typeAliasDef": {
- "typeParams": [],
- "tsType": {
- "repr": "Array",
- "kind": "typeRef",
- "typeRef": {
- "typeParams": [
- {
- "repr": "number",
- "kind": "keyword",
- "keyword": "number"
- }
- ],
- "typeName": "Array"
- }
- }
- }
- }]);
-
- json_test!(export_namespace,
- r#"
-/** Namespace JSdoc */
-export namespace RootNs {
- export const a = "a";
-
- /** Nested namespace JSDoc */
- export namespace NestedNs {
- export enum Foo {
- a = 1,
- b = 2,
- c = 3,
- }
- }
-}
- "#;
- [{
- "kind": "namespace",
- "name": "RootNs",
- "location": {
- "filename": "test.ts",
- "line": 3,
- "col": 0
- },
- "jsDoc": "Namespace JSdoc",
- "namespaceDef": {
- "elements": [
- {
- "kind": "variable",
- "name": "a",
- "location": {
- "filename": "test.ts",
- "line": 4,
- "col": 4
- },
- "jsDoc": null,
- "variableDef": {
- "tsType": null,
- "kind": "const"
- }
- },
- {
- "kind": "namespace",
- "name": "NestedNs",
- "location": {
- "filename": "test.ts",
- "line": 7,
- "col": 4
- },
- "jsDoc": "Nested namespace JSDoc",
- "namespaceDef": {
- "elements": [
- {
- "kind": "enum",
- "name": "Foo",
- "location": {
- "filename": "test.ts",
- "line": 8,
- "col": 6
- },
- "jsDoc": null,
- "enumDef": {
- "members": [
- {
- "name": "a"
- },
- {
- "name": "b"
- },
- {
- "name": "c"
- }
- ]
- }
- }
- ]
- }
- }
- ]
- }
- }]);
-
- json_test!(optional_return_type,
- r#"
- export function foo(a: number) {
- return a;
- }
- "#;
- [{
- "kind": "function",
- "name": "foo",
- "location": {
- "filename": "test.ts",
- "line": 2,
- "col": 2
- },
- "jsDoc": null,
- "functionDef": {
- "params": [
- {
- "name": "a",
- "kind": "identifier",
- "optional": false,
- "tsType": {
- "keyword": "number",
- "kind": "keyword",
- "repr": "number",
- },
- }
- ],
- "typeParams": [],
- "returnType": null,
- "isAsync": false,
- "isGenerator": false
- }
- }]
- );
-
- json_test!(ts_lit_types,
- r#"
-export type boolLit = false;
-export type strLit = "text";
-export type tplLit = `text`;
-export type numLit = 5;
- "#;
- [
- {
- "kind": "typeAlias",
- "name": "boolLit",
- "location": {
- "filename": "test.ts",
- "line": 2,
- "col": 0
- },
- "jsDoc": null,
- "typeAliasDef": {
- "tsType": {
- "repr": "false",
- "kind": "literal",
- "literal": {
- "kind": "boolean",
- "boolean": false
- }
- },
- "typeParams": []
- }
- }, {
- "kind": "typeAlias",
- "name": "strLit",
- "location": {
- "filename": "test.ts",
- "line": 3,
- "col": 0
- },
- "jsDoc": null,
- "typeAliasDef": {
- "tsType": {
- "repr": "text",
- "kind": "literal",
- "literal": {
- "kind": "string",
- "string": "text"
- }
- },
- "typeParams": []
- }
- }, {
- "kind": "typeAlias",
- "name": "tplLit",
- "location": {
- "filename": "test.ts",
- "line": 4,
- "col": 0
- },
- "jsDoc": null,
- "typeAliasDef": {
- "tsType": {
- "repr": "text",
- "kind": "literal",
- "literal": {
- "kind": "string",
- "string": "text"
- }
- },
- "typeParams": []
- }
- }, {
- "kind": "typeAlias",
- "name": "numLit",
- "location": {
- "filename": "test.ts",
- "line": 5,
- "col": 0
- },
- "jsDoc": null,
- "typeAliasDef": {
- "tsType": {
- "repr": "5",
- "kind": "literal",
- "literal": {
- "kind": "number",
- "number": 5.0
- }
- },
- "typeParams": []
- }
- }
- ]);
-}
-
-mod printer {
- use super::*;
-
- contains_test!(abstract_class,
- "export abstract class Class {}";
- "abstract class Class"
- );
-
- contains_test!(abstract_class_abstract_method,
- r#"
-export abstract class Class {
- abstract method() {}
-}
- "#;
- "abstract method()"
- );
-
- contains_test!(class_async_method,
- r#"
-export class Class {
- async amethod(v) {}
-}
- "#;
- "async amethod(v)"
- );
-
- contains_test!(class_constructor,
- r#"
-export class Class {
- constructor(a, b) {}
-}
- "#;
- "constructor(a, b)"
- );
-
- contains_test!(class_details,
- r#"
-export class C {
- /** a doc */
- a() {}
- f: number;
-}
- "#;
- "class C",
- "a()",
- "f: number"
- );
-
- contains_test!(class_details_all_with_private,
- r#"
-export class Class {
- private pri() {}
- protected pro() {}
- public pub() {}
-}
- "#,
- private;
- "private pri()",
- "protected pro()",
- "pub()"
- );
-
- contains_test!(class_details_only_non_private_without_private,
- r#"
-export class Class {
- private pri() {}
- protected pro() {}
- public pub() {}
-}
- "#;
- "protected pro()",
- "pub()"
- );
-
- contains_test!(class_declaration,
- "export class Class {}";
- "class Class"
- );
-
- contains_test!(class_extends,
- "export class Class extends Object {}";
- "class Class extends Object"
- );
-
- contains_test!(class_extends_implements,
- "export class Class extends Object implements Iterator, Iterable {}";
- "class Class extends Object implements Iterator, Iterable"
- );
-
- contains_test!(class_generic_extends_implements,
- "export class Class<A, B> extends Map<A, B> implements Iterator<A>, Iterable<B> {}";
- "class Class<A, B> extends Map<A, B> implements Iterator<A>, Iterable<B>"
- );
-
- contains_test!(class_getter_and_setter,
- r#"
-export class Class {
- get a(): void {}
- set b(_v: void) {}
-}
- "#;
- "get a(): void",
- "set b(_v: void)"
- );
-
- contains_test!(class_index_signature,
- r#"
-export class C {
- [key: string]: number;
-}
- "#;
- "[key: string]: number"
- );
-
- contains_test!(class_implements,
- "export class Class implements Iterator {}";
- "class Class implements Iterator"
- );
-
- contains_test!(class_implements2,
- "export class Class implements Iterator, Iterable {}";
- "class Class implements Iterator, Iterable"
- );
-
- contains_test!(class_method,
- r#"
-export class Class {
- method(v) {}
-}
- "#;
- "method(v)"
- );
-
- contains_test!(class_property,
- r#"
-export class Class {
- someproperty: bool;
- optproperty: bigint;
-}
- "#;
- "someproperty: bool",
- "optproperty: bigint"
- );
-
- contains_test!(class_readonly_index_signature,
- r#"
-export class C {
- readonly [key: string]: number;
-}
- "#;
- "readonly [key: string]: number"
- );
-
- contains_test!(class_static_property,
- r#"
-export class Class {
- static property = "";
-}
- "#;
- "static property"
- );
-
- contains_test!(class_readonly_property,
- r#"
-export class Class {
- readonly property = "";
-}
- "#;
- "readonly property"
- );
-
- contains_test!(class_private_property,
- r#"
-export class Class {
- private property = "";
-}
- "#,
- private;
- "private property"
- );
-
- contains_test!(const_declaration,
- "export const Const = 0;";
- "const Const"
- );
-
- contains_test!(enum_declaration,
- "export enum Enum {}";
- "enum Enum"
- );
-
- contains_test!(exports_all_with_private,
- r#"
-export function a() {}
-function b() {}
-export class C {}
-class D {}
-export interface E {}
-interface F {}
-export namespace G {}
-namespace H {}
- "#,
- private;
- "function a()",
- "class C",
- "interface E",
- "namespace G",
- "function b()",
- "class D",
- "interface F",
- "namespace H"
- );
-
- contains_test!(function_async,
- "export async function a() {}";
- "async function a()"
- );
-
- contains_test!(function_array_deconstruction,
- "export function f([a, b, ...c]) {}";
- "function f([a, b, ...c])"
- );
-
- contains_test!(function_async_generator,
- "export async function* ag() {}";
- "async function* ag()"
- );
-
- contains_test!(function_declaration,
- "export function fun() {}";
- "function fun()"
- );
-
- contains_test!(function_generator,
- "export function* g() {}";
- "function* g()"
- );
-
- contains_test!(function_generic,
- "export function add<T>(a: T, b: T) { return a + b; }";
- "function add<T>(a: T, b: T)"
- );
-
- contains_test!(function_object_deconstruction,
- "export function f({ a, b, ...c }) {}";
- "function f({a, b, ...c})"
- );
-
- /* TODO(SyrupThinker) NYI
- contains_test!(function_type_predicate,
- r#"
- export function isFish(pet: Fish | Bird): pet is Fish {
- return (pet as Fish).swim !== undefined;
- }
- "#;
- "pet is Fish"
- );
- */
-
- contains_test!(generic_instantiated_with_tuple_type,
- r#"
-interface Generic<T> {}
-export function f(): Generic<[string, number]> { return {}; }
- "#;
- "Generic<[string, number]>"
- );
-
- contains_test!(type_literal_declaration,
- "export type T = {}";
- "{ }"
- );
-
- contains_test!(type_literal_index_signature,
- "export type T = { [key: string]: number; }";
- "[key: string]: number"
- );
-
- contains_test!(type_literal_readonly_index_signature,
- "export type T = { readonly [key: string]: number; }";
- "readonly [key: string]: number"
- );
-
- contains_test!(interface_declaration,
- "export interface Interface {}";
- "interface Interface"
- );
-
- contains_test!(interface_extends,
- "export interface Interface extends Iterator {}";
- "interface Interface extends Iterator"
- );
-
- contains_test!(interface_extends2,
- "export interface Interface extends Iterator, Iterable {}";
- "interface Interface extends Iterator, Iterable"
- );
-
- contains_test!(interface_generic,
- "export interface Interface<T> {}";
- "interface Interface<T>"
- );
-
- contains_test!(interface_generic_extends,
- "export interface Interface<V> extends Iterable<V> {}";
- "interface Interface<V> extends Iterable<V>"
- );
-
- contains_test!(interface_index_signature,
- r#"
-export interface Interface {
- [index: number]: Interface;
-}
- "#;
- "[index: number]: Interface"
- );
-
- contains_test!(interface_method,
- r#"
-export interface I {
- m(a, b);
- mo?(c);
-}
- "#;
- "m(a, b)",
- "mo?(c)"
- );
-
- contains_test!(interface_property,
- r#"
-export interface I {
- p: string;
- po?: number;
-}
- "#;
- "p: string",
- "po?: number"
- );
-
- contains_test!(interface_readonly_index_signature,
- r#"
-export interface Interface {
- readonly [index: number]: Interface;
-}
- "#;
- "readonly [index: number]: Interface"
- );
-
- contains_test!(jsdoc,
- r#"
-/**
- * A is a class
- *
- * Nothing more
- */
-export class A {}
-/**
- * B is an interface
- *
- * Should be
- */
-export interface B {}
-/**
- * C is a function
- *
- * Summarised
- */
-export function C() {}
- "#;
- "A is a class",
- "B is an interface",
- "C is a function",
- "Nothing more",
- "Should be",
- "Summarised"
- );
-
- contains_test!(namespace_declaration,
- "export namespace Namespace {}";
- "namespace Namespace"
- );
-
- contains_test!(namespace_details,
- r#"
-export namespace Namespace {
- /**
- * Doc comment 1
- *
- * Details 1
- */
- export function a() {}
- /**
- * Doc comment 2
- *
- * Details 2
- */
- export class B {}
-}
- "#;
- "namespace Namespace",
- "function a()",
- "class B",
- "Doc comment 1",
- "Doc comment 2",
- "Details 1",
- "Details 2"
- );
-
- contains_test!(type_alias,
- "export type A = number";
- "type A = number"
- );
-
- contains_test!(type_generic_alias,
- "export type A<T> = T";
- "type A<T> = T"
- );
-}
diff --git a/cli/doc/ts_type.rs b/cli/doc/ts_type.rs
deleted file mode 100644
index b2eb3438d..000000000
--- a/cli/doc/ts_type.rs
+++ /dev/null
@@ -1,985 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-use super::display::{display_readonly, SliceDisplayer};
-use super::interface::expr_to_name;
-use super::params::ts_fn_param_to_param_def;
-use super::ts_type_param::maybe_type_param_decl_to_type_param_defs;
-use super::ts_type_param::TsTypeParamDef;
-use super::ParamDef;
-use crate::colors;
-use crate::doc;
-use serde::Serialize;
-use std::fmt::{Display, Formatter, Result as FmtResult};
-use swc_ecmascript::ast::{
- TsArrayType, TsConditionalType, TsExprWithTypeArgs, TsFnOrConstructorType,
- TsIndexedAccessType, TsKeywordType, TsLit, TsLitType, TsOptionalType,
- TsParenthesizedType, TsRestType, TsThisType, TsTupleType, TsType, TsTypeAnn,
- TsTypeLit, TsTypeOperator, TsTypeParamInstantiation, TsTypeQuery, TsTypeRef,
- TsUnionOrIntersectionType,
-};
-
-// pub enum TsType {
-// * TsKeywordType(TsKeywordType),
-// * TsThisType(TsThisType),
-// * TsFnOrConstructorType(TsFnOrConstructorType),
-// * TsTypeRef(TsTypeRef),
-// * TsTypeQuery(TsTypeQuery),
-// * TsTypeLit(TsTypeLit),
-// * TsArrayType(TsArrayType),
-// * TsTupleType(TsTupleType),
-// * TsOptionalType(TsOptionalType),
-// * TsRestType(TsRestType),
-// * TsUnionOrIntersectionType(TsUnionOrIntersectionType),
-// * TsConditionalType(TsConditionalType),
-// * TsParenthesizedType(TsParenthesizedType),
-// * TsTypeOperator(TsTypeOperator),
-// * TsIndexedAccessType(TsIndexedAccessType),
-// * TsLitType(TsLitType),
-// TsInferType(TsInferType),
-// TsMappedType(TsMappedType),
-// TsTypePredicate(TsTypePredicate),
-// TsImportType(TsImportType),
-// }
-
-impl Into<TsTypeDef> for &TsLitType {
- fn into(self) -> TsTypeDef {
- let (repr, lit) = match &self.lit {
- TsLit::Number(num) => (
- format!("{}", num.value),
- LiteralDef {
- kind: LiteralDefKind::Number,
- number: Some(num.value),
- string: None,
- boolean: None,
- },
- ),
- TsLit::Str(str_) => (
- str_.value.to_string(),
- LiteralDef {
- kind: LiteralDefKind::String,
- number: None,
- string: Some(str_.value.to_string()),
- boolean: None,
- },
- ),
- TsLit::Tpl(tpl) => {
- // A template literal in a type is not allowed to have
- // expressions, so there will only be one quasi.
- let quasi = tpl.quasis.get(0).expect("Expected tpl to have a quasi.");
- let text = quasi.raw.value.to_string();
- (
- text.clone(),
- LiteralDef {
- kind: LiteralDefKind::String, // semantically the same
- number: None,
- string: Some(text),
- boolean: None,
- },
- )
- }
- TsLit::Bool(bool_) => (
- bool_.value.to_string(),
- LiteralDef {
- kind: LiteralDefKind::Boolean,
- number: None,
- string: None,
- boolean: Some(bool_.value),
- },
- ),
- };
-
- TsTypeDef {
- repr,
- kind: Some(TsTypeDefKind::Literal),
- literal: Some(lit),
- ..Default::default()
- }
- }
-}
-
-impl Into<TsTypeDef> for &TsArrayType {
- fn into(self) -> TsTypeDef {
- let ts_type_def: TsTypeDef = (&*self.elem_type).into();
-
- TsTypeDef {
- array: Some(Box::new(ts_type_def)),
- kind: Some(TsTypeDefKind::Array),
- ..Default::default()
- }
- }
-}
-
-impl Into<TsTypeDef> for &TsTupleType {
- fn into(self) -> TsTypeDef {
- let mut type_defs = vec![];
-
- for type_box in &self.elem_types {
- let ts_type: &TsType = &type_box.ty;
- let def: TsTypeDef = ts_type.into();
- type_defs.push(def)
- }
-
- TsTypeDef {
- tuple: Some(type_defs),
- kind: Some(TsTypeDefKind::Tuple),
- ..Default::default()
- }
- }
-}
-
-impl Into<TsTypeDef> for &TsUnionOrIntersectionType {
- fn into(self) -> TsTypeDef {
- use swc_ecmascript::ast::TsUnionOrIntersectionType::*;
-
- match self {
- TsUnionType(union_type) => {
- let mut types_union = vec![];
-
- for type_box in &union_type.types {
- let ts_type: &TsType = &(*type_box);
- let def: TsTypeDef = ts_type.into();
- types_union.push(def);
- }
-
- TsTypeDef {
- union: Some(types_union),
- kind: Some(TsTypeDefKind::Union),
- ..Default::default()
- }
- }
- TsIntersectionType(intersection_type) => {
- let mut types_intersection = vec![];
-
- for type_box in &intersection_type.types {
- let ts_type: &TsType = &(*type_box);
- let def: TsTypeDef = ts_type.into();
- types_intersection.push(def);
- }
-
- TsTypeDef {
- intersection: Some(types_intersection),
- kind: Some(TsTypeDefKind::Intersection),
- ..Default::default()
- }
- }
- }
- }
-}
-
-impl Into<TsTypeDef> for &TsKeywordType {
- fn into(self) -> TsTypeDef {
- use swc_ecmascript::ast::TsKeywordTypeKind::*;
-
- let keyword_str = match self.kind {
- TsAnyKeyword => "any",
- TsUnknownKeyword => "unknown",
- TsNumberKeyword => "number",
- TsObjectKeyword => "object",
- TsBooleanKeyword => "boolean",
- TsBigIntKeyword => "bigint",
- TsStringKeyword => "string",
- TsSymbolKeyword => "symbol",
- TsVoidKeyword => "void",
- TsUndefinedKeyword => "undefined",
- TsNullKeyword => "null",
- TsNeverKeyword => "never",
- };
-
- TsTypeDef {
- repr: keyword_str.to_string(),
- kind: Some(TsTypeDefKind::Keyword),
- keyword: Some(keyword_str.to_string()),
- ..Default::default()
- }
- }
-}
-
-impl Into<TsTypeDef> for &TsTypeOperator {
- fn into(self) -> TsTypeDef {
- let ts_type = (&*self.type_ann).into();
- let type_operator_def = TsTypeOperatorDef {
- operator: self.op.as_str().to_string(),
- ts_type,
- };
-
- TsTypeDef {
- type_operator: Some(Box::new(type_operator_def)),
- kind: Some(TsTypeDefKind::TypeOperator),
- ..Default::default()
- }
- }
-}
-
-impl Into<TsTypeDef> for &TsParenthesizedType {
- fn into(self) -> TsTypeDef {
- let ts_type = (&*self.type_ann).into();
-
- TsTypeDef {
- parenthesized: Some(Box::new(ts_type)),
- kind: Some(TsTypeDefKind::Parenthesized),
- ..Default::default()
- }
- }
-}
-
-impl Into<TsTypeDef> for &TsRestType {
- fn into(self) -> TsTypeDef {
- let ts_type = (&*self.type_ann).into();
-
- TsTypeDef {
- rest: Some(Box::new(ts_type)),
- kind: Some(TsTypeDefKind::Rest),
- ..Default::default()
- }
- }
-}
-
-impl Into<TsTypeDef> for &TsOptionalType {
- fn into(self) -> TsTypeDef {
- let ts_type = (&*self.type_ann).into();
-
- TsTypeDef {
- optional: Some(Box::new(ts_type)),
- kind: Some(TsTypeDefKind::Optional),
- ..Default::default()
- }
- }
-}
-
-impl Into<TsTypeDef> for &TsThisType {
- fn into(self) -> TsTypeDef {
- TsTypeDef {
- repr: "this".to_string(),
- this: Some(true),
- kind: Some(TsTypeDefKind::This),
- ..Default::default()
- }
- }
-}
-
-pub fn ts_entity_name_to_name(
- entity_name: &swc_ecmascript::ast::TsEntityName,
-) -> String {
- use swc_ecmascript::ast::TsEntityName::*;
-
- match entity_name {
- Ident(ident) => ident.sym.to_string(),
- TsQualifiedName(ts_qualified_name) => {
- let left = ts_entity_name_to_name(&ts_qualified_name.left);
- let right = ts_qualified_name.right.sym.to_string();
- format!("{}.{}", left, right)
- }
- }
-}
-
-impl Into<TsTypeDef> for &TsTypeQuery {
- fn into(self) -> TsTypeDef {
- use swc_ecmascript::ast::TsTypeQueryExpr::*;
-
- let type_name = match &self.expr_name {
- TsEntityName(entity_name) => ts_entity_name_to_name(&*entity_name),
- Import(import_type) => import_type.arg.value.to_string(),
- };
-
- TsTypeDef {
- repr: type_name.to_string(),
- type_query: Some(type_name),
- kind: Some(TsTypeDefKind::TypeQuery),
- ..Default::default()
- }
- }
-}
-
-impl Into<TsTypeDef> for &TsTypeRef {
- fn into(self) -> TsTypeDef {
- let type_name = ts_entity_name_to_name(&self.type_name);
-
- let type_params = if let Some(type_params_inst) = &self.type_params {
- let mut ts_type_defs = vec![];
-
- for type_box in &type_params_inst.params {
- let ts_type: &TsType = &(*type_box);
- let def: TsTypeDef = ts_type.into();
- ts_type_defs.push(def);
- }
-
- Some(ts_type_defs)
- } else {
- None
- };
-
- TsTypeDef {
- repr: type_name.clone(),
- type_ref: Some(TsTypeRefDef {
- type_name,
- type_params,
- }),
- kind: Some(TsTypeDefKind::TypeRef),
- ..Default::default()
- }
- }
-}
-
-impl Into<TsTypeDef> for &TsExprWithTypeArgs {
- fn into(self) -> TsTypeDef {
- let type_name = ts_entity_name_to_name(&self.expr);
-
- let type_params = if let Some(type_params_inst) = &self.type_args {
- let mut ts_type_defs = vec![];
-
- for type_box in &type_params_inst.params {
- let ts_type: &TsType = &(*type_box);
- let def: TsTypeDef = ts_type.into();
- ts_type_defs.push(def);
- }
-
- Some(ts_type_defs)
- } else {
- None
- };
-
- TsTypeDef {
- repr: type_name.clone(),
- type_ref: Some(TsTypeRefDef {
- type_name,
- type_params,
- }),
- kind: Some(TsTypeDefKind::TypeRef),
- ..Default::default()
- }
- }
-}
-
-impl Into<TsTypeDef> for &TsIndexedAccessType {
- fn into(self) -> TsTypeDef {
- let indexed_access_def = TsIndexedAccessDef {
- readonly: self.readonly,
- obj_type: Box::new((&*self.obj_type).into()),
- index_type: Box::new((&*self.index_type).into()),
- };
-
- TsTypeDef {
- indexed_access: Some(indexed_access_def),
- kind: Some(TsTypeDefKind::IndexedAccess),
- ..Default::default()
- }
- }
-}
-
-impl Into<TsTypeDef> for &TsTypeLit {
- fn into(self) -> TsTypeDef {
- let mut methods = vec![];
- let mut properties = vec![];
- let mut call_signatures = vec![];
- let mut index_signatures = vec![];
-
- for type_element in &self.members {
- use swc_ecmascript::ast::TsTypeElement::*;
-
- match &type_element {
- TsMethodSignature(ts_method_sig) => {
- let mut params = vec![];
-
- for param in &ts_method_sig.params {
- let param_def = ts_fn_param_to_param_def(param, None);
- params.push(param_def);
- }
-
- let maybe_return_type = ts_method_sig
- .type_ann
- .as_ref()
- .map(|rt| (&*rt.type_ann).into());
-
- let type_params = maybe_type_param_decl_to_type_param_defs(
- ts_method_sig.type_params.as_ref(),
- );
- let name = expr_to_name(&*ts_method_sig.key);
- let method_def = LiteralMethodDef {
- name,
- params,
- return_type: maybe_return_type,
- type_params,
- };
- methods.push(method_def);
- }
- TsPropertySignature(ts_prop_sig) => {
- let name = expr_to_name(&*ts_prop_sig.key);
-
- let mut params = vec![];
-
- for param in &ts_prop_sig.params {
- let param_def = ts_fn_param_to_param_def(param, None);
- params.push(param_def);
- }
-
- let ts_type = ts_prop_sig
- .type_ann
- .as_ref()
- .map(|rt| (&*rt.type_ann).into());
-
- let type_params = maybe_type_param_decl_to_type_param_defs(
- ts_prop_sig.type_params.as_ref(),
- );
- let prop_def = LiteralPropertyDef {
- name,
- params,
- ts_type,
- computed: ts_prop_sig.computed,
- optional: ts_prop_sig.optional,
- type_params,
- };
- properties.push(prop_def);
- }
- TsCallSignatureDecl(ts_call_sig) => {
- let mut params = vec![];
- for param in &ts_call_sig.params {
- let param_def = ts_fn_param_to_param_def(param, None);
- params.push(param_def);
- }
-
- let ts_type = ts_call_sig
- .type_ann
- .as_ref()
- .map(|rt| (&*rt.type_ann).into());
-
- let type_params = maybe_type_param_decl_to_type_param_defs(
- ts_call_sig.type_params.as_ref(),
- );
-
- let call_sig_def = LiteralCallSignatureDef {
- params,
- ts_type,
- type_params,
- };
- call_signatures.push(call_sig_def);
- }
- TsIndexSignature(ts_index_sig) => {
- let mut params = vec![];
- for param in &ts_index_sig.params {
- let param_def = ts_fn_param_to_param_def(param, None);
- params.push(param_def);
- }
-
- let ts_type = ts_index_sig
- .type_ann
- .as_ref()
- .map(|rt| (&*rt.type_ann).into());
-
- let index_sig_def = LiteralIndexSignatureDef {
- readonly: ts_index_sig.readonly,
- params,
- ts_type,
- };
- index_signatures.push(index_sig_def);
- }
- // TODO:
- TsConstructSignatureDecl(_) => {}
- }
- }
-
- let type_literal = TsTypeLiteralDef {
- methods,
- properties,
- call_signatures,
- index_signatures,
- };
-
- TsTypeDef {
- kind: Some(TsTypeDefKind::TypeLiteral),
- type_literal: Some(type_literal),
- ..Default::default()
- }
- }
-}
-
-impl Into<TsTypeDef> for &TsConditionalType {
- fn into(self) -> TsTypeDef {
- let conditional_type_def = TsConditionalDef {
- check_type: Box::new((&*self.check_type).into()),
- extends_type: Box::new((&*self.extends_type).into()),
- true_type: Box::new((&*self.true_type).into()),
- false_type: Box::new((&*self.false_type).into()),
- };
-
- TsTypeDef {
- kind: Some(TsTypeDefKind::Conditional),
- conditional_type: Some(conditional_type_def),
- ..Default::default()
- }
- }
-}
-
-impl Into<TsTypeDef> for &TsFnOrConstructorType {
- fn into(self) -> TsTypeDef {
- use swc_ecmascript::ast::TsFnOrConstructorType::*;
-
- let fn_def = match self {
- TsFnType(ts_fn_type) => {
- let mut params = vec![];
-
- for param in &ts_fn_type.params {
- let param_def = ts_fn_param_to_param_def(param, None);
- params.push(param_def);
- }
-
- let type_params = maybe_type_param_decl_to_type_param_defs(
- ts_fn_type.type_params.as_ref(),
- );
-
- TsFnOrConstructorDef {
- constructor: false,
- ts_type: ts_type_ann_to_def(&ts_fn_type.type_ann),
- params,
- type_params,
- }
- }
- TsConstructorType(ctor_type) => {
- let mut params = vec![];
-
- for param in &ctor_type.params {
- let param_def = ts_fn_param_to_param_def(param, None);
- params.push(param_def);
- }
-
- let type_params = maybe_type_param_decl_to_type_param_defs(
- ctor_type.type_params.as_ref(),
- );
- TsFnOrConstructorDef {
- constructor: true,
- ts_type: ts_type_ann_to_def(&ctor_type.type_ann),
- params,
- type_params,
- }
- }
- };
-
- TsTypeDef {
- kind: Some(TsTypeDefKind::FnOrConstructor),
- fn_or_constructor: Some(Box::new(fn_def)),
- ..Default::default()
- }
- }
-}
-
-impl Into<TsTypeDef> for &TsType {
- fn into(self) -> TsTypeDef {
- use swc_ecmascript::ast::TsType::*;
-
- match self {
- TsKeywordType(ref keyword_type) => keyword_type.into(),
- TsLitType(ref lit_type) => lit_type.into(),
- TsTypeRef(ref type_ref) => type_ref.into(),
- TsUnionOrIntersectionType(union_or_inter) => union_or_inter.into(),
- TsArrayType(array_type) => array_type.into(),
- TsTupleType(tuple_type) => tuple_type.into(),
- TsTypeOperator(type_op_type) => type_op_type.into(),
- TsParenthesizedType(paren_type) => paren_type.into(),
- TsRestType(rest_type) => rest_type.into(),
- TsOptionalType(optional_type) => optional_type.into(),
- TsTypeQuery(type_query) => type_query.into(),
- TsThisType(this_type) => this_type.into(),
- TsFnOrConstructorType(fn_or_con_type) => fn_or_con_type.into(),
- TsConditionalType(conditional_type) => conditional_type.into(),
- TsIndexedAccessType(indexed_access_type) => indexed_access_type.into(),
- TsTypeLit(type_literal) => type_literal.into(),
- _ => TsTypeDef {
- repr: "<UNIMPLEMENTED>".to_string(),
- ..Default::default()
- },
- }
- }
-}
-
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct TsTypeRefDef {
- pub type_params: Option<Vec<TsTypeDef>>,
- pub type_name: String,
-}
-
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub enum LiteralDefKind {
- Number,
- String,
- Boolean,
-}
-
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct LiteralDef {
- pub kind: LiteralDefKind,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub number: Option<f64>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub string: Option<String>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub boolean: Option<bool>,
-}
-
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct TsTypeOperatorDef {
- pub operator: String,
- pub ts_type: TsTypeDef,
-}
-
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct TsFnOrConstructorDef {
- pub constructor: bool,
- pub ts_type: TsTypeDef,
- pub params: Vec<ParamDef>,
- pub type_params: Vec<TsTypeParamDef>,
-}
-
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct TsConditionalDef {
- pub check_type: Box<TsTypeDef>,
- pub extends_type: Box<TsTypeDef>,
- pub true_type: Box<TsTypeDef>,
- pub false_type: Box<TsTypeDef>,
-}
-
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct TsIndexedAccessDef {
- pub readonly: bool,
- pub obj_type: Box<TsTypeDef>,
- pub index_type: Box<TsTypeDef>,
-}
-
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct LiteralMethodDef {
- pub name: String,
- pub params: Vec<ParamDef>,
- pub return_type: Option<TsTypeDef>,
- pub type_params: Vec<TsTypeParamDef>,
-}
-
-impl Display for LiteralMethodDef {
- fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
- write!(
- f,
- "{}({})",
- self.name,
- SliceDisplayer::new(&self.params, ", ", false)
- )?;
- if let Some(return_type) = &self.return_type {
- write!(f, ": {}", return_type)?;
- }
- Ok(())
- }
-}
-
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct LiteralPropertyDef {
- pub name: String,
- pub params: Vec<ParamDef>,
- pub computed: bool,
- pub optional: bool,
- pub ts_type: Option<TsTypeDef>,
- pub type_params: Vec<TsTypeParamDef>,
-}
-
-impl Display for LiteralPropertyDef {
- fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
- write!(f, "{}", self.name)?;
- if let Some(ts_type) = &self.ts_type {
- write!(f, ": {}", ts_type)?;
- }
- Ok(())
- }
-}
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct LiteralCallSignatureDef {
- pub params: Vec<ParamDef>,
- pub ts_type: Option<TsTypeDef>,
- pub type_params: Vec<TsTypeParamDef>,
-}
-
-impl Display for LiteralCallSignatureDef {
- fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
- write!(f, "({})", SliceDisplayer::new(&self.params, ", ", false))?;
- if let Some(ts_type) = &self.ts_type {
- write!(f, ": {}", ts_type)?;
- }
- Ok(())
- }
-}
-
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct LiteralIndexSignatureDef {
- pub readonly: bool,
- pub params: Vec<ParamDef>,
- pub ts_type: Option<TsTypeDef>,
-}
-
-impl Display for LiteralIndexSignatureDef {
- fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
- write!(
- f,
- "{}[{}]",
- display_readonly(self.readonly),
- SliceDisplayer::new(&self.params, ", ", false)
- )?;
- if let Some(ts_type) = &self.ts_type {
- write!(f, ": {}", ts_type)?;
- }
- Ok(())
- }
-}
-
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct TsTypeLiteralDef {
- pub methods: Vec<LiteralMethodDef>,
- pub properties: Vec<LiteralPropertyDef>,
- pub call_signatures: Vec<LiteralCallSignatureDef>,
- pub index_signatures: Vec<LiteralIndexSignatureDef>,
-}
-
-#[derive(Debug, PartialEq, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub enum TsTypeDefKind {
- Keyword,
- Literal,
- TypeRef,
- Union,
- Intersection,
- Array,
- Tuple,
- TypeOperator,
- Parenthesized,
- Rest,
- Optional,
- TypeQuery,
- This,
- FnOrConstructor,
- Conditional,
- IndexedAccess,
- TypeLiteral,
-}
-
-#[derive(Debug, Default, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct TsTypeDef {
- pub repr: String,
-
- pub kind: Option<TsTypeDefKind>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub keyword: Option<String>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub literal: Option<LiteralDef>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub type_ref: Option<TsTypeRefDef>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub union: Option<Vec<TsTypeDef>>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub intersection: Option<Vec<TsTypeDef>>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub array: Option<Box<TsTypeDef>>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub tuple: Option<Vec<TsTypeDef>>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub type_operator: Option<Box<TsTypeOperatorDef>>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub parenthesized: Option<Box<TsTypeDef>>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub rest: Option<Box<TsTypeDef>>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub optional: Option<Box<TsTypeDef>>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub type_query: Option<String>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub this: Option<bool>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub fn_or_constructor: Option<Box<TsFnOrConstructorDef>>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub conditional_type: Option<TsConditionalDef>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub indexed_access: Option<TsIndexedAccessDef>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub type_literal: Option<TsTypeLiteralDef>,
-}
-
-pub fn ts_type_ann_to_def(type_ann: &TsTypeAnn) -> TsTypeDef {
- use swc_ecmascript::ast::TsType::*;
-
- match &*type_ann.type_ann {
- TsKeywordType(keyword_type) => keyword_type.into(),
- TsLitType(lit_type) => lit_type.into(),
- TsTypeRef(type_ref) => type_ref.into(),
- TsUnionOrIntersectionType(union_or_inter) => union_or_inter.into(),
- TsArrayType(array_type) => array_type.into(),
- TsTupleType(tuple_type) => tuple_type.into(),
- TsTypeOperator(type_op_type) => type_op_type.into(),
- TsParenthesizedType(paren_type) => paren_type.into(),
- TsRestType(rest_type) => rest_type.into(),
- TsOptionalType(optional_type) => optional_type.into(),
- TsTypeQuery(type_query) => type_query.into(),
- TsThisType(this_type) => this_type.into(),
- TsFnOrConstructorType(fn_or_con_type) => fn_or_con_type.into(),
- TsConditionalType(conditional_type) => conditional_type.into(),
- TsIndexedAccessType(indexed_access_type) => indexed_access_type.into(),
- TsTypeLit(type_literal) => type_literal.into(),
- _ => TsTypeDef {
- repr: "<TODO>".to_string(),
- ..Default::default()
- },
- }
-}
-
-impl Display for TsTypeDef {
- fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
- if self.kind.is_none() {
- return write!(f, "{}", colors::red("<UNIMPLEMENTED>"));
- }
-
- let kind = self.kind.as_ref().unwrap();
- match kind {
- TsTypeDefKind::Array => write!(f, "{}[]", &*self.array.as_ref().unwrap()),
- TsTypeDefKind::Conditional => {
- let conditional = self.conditional_type.as_ref().unwrap();
- write!(
- f,
- "{} {} {} ? {} : {}",
- &*conditional.check_type,
- colors::magenta("extends"),
- &*conditional.extends_type,
- &*conditional.true_type,
- &*conditional.false_type
- )
- }
- TsTypeDefKind::FnOrConstructor => {
- let fn_or_constructor = self.fn_or_constructor.as_ref().unwrap();
- write!(
- f,
- "{}({}) => {}",
- colors::magenta(if fn_or_constructor.constructor {
- "new "
- } else {
- ""
- }),
- SliceDisplayer::new(&fn_or_constructor.params, ", ", false),
- &fn_or_constructor.ts_type,
- )
- }
- TsTypeDefKind::IndexedAccess => {
- let indexed_access = self.indexed_access.as_ref().unwrap();
- write!(
- f,
- "{}[{}]",
- &*indexed_access.obj_type, &*indexed_access.index_type
- )
- }
- TsTypeDefKind::Intersection => {
- let intersection = self.intersection.as_ref().unwrap();
- write!(f, "{}", SliceDisplayer::new(&intersection, " & ", false))
- }
- TsTypeDefKind::Keyword => {
- write!(f, "{}", colors::cyan(self.keyword.as_ref().unwrap()))
- }
- TsTypeDefKind::Literal => {
- let literal = self.literal.as_ref().unwrap();
- match literal.kind {
- doc::ts_type::LiteralDefKind::Boolean => write!(
- f,
- "{}",
- colors::yellow(&literal.boolean.unwrap().to_string())
- ),
- doc::ts_type::LiteralDefKind::String => write!(
- f,
- "{}",
- colors::green(&format!("\"{}\"", literal.string.as_ref().unwrap()))
- ),
- doc::ts_type::LiteralDefKind::Number => write!(
- f,
- "{}",
- colors::yellow(&literal.number.unwrap().to_string())
- ),
- }
- }
- TsTypeDefKind::Optional => {
- write!(f, "{}?", &*self.optional.as_ref().unwrap())
- }
- TsTypeDefKind::Parenthesized => {
- write!(f, "({})", &*self.parenthesized.as_ref().unwrap())
- }
- TsTypeDefKind::Rest => write!(f, "...{}", &*self.rest.as_ref().unwrap()),
- TsTypeDefKind::This => write!(f, "this"),
- TsTypeDefKind::Tuple => {
- let tuple = self.tuple.as_ref().unwrap();
- write!(f, "[{}]", SliceDisplayer::new(&tuple, ", ", false))
- }
- TsTypeDefKind::TypeLiteral => {
- let type_literal = self.type_literal.as_ref().unwrap();
- write!(
- f,
- "{{ {}{}{}{}}}",
- SliceDisplayer::new(&type_literal.call_signatures, "; ", true),
- SliceDisplayer::new(&type_literal.methods, "; ", true),
- SliceDisplayer::new(&type_literal.properties, "; ", true),
- SliceDisplayer::new(&type_literal.index_signatures, "; ", true),
- )
- }
- TsTypeDefKind::TypeOperator => {
- let operator = self.type_operator.as_ref().unwrap();
- write!(f, "{} {}", operator.operator, &operator.ts_type)
- }
- TsTypeDefKind::TypeQuery => {
- write!(f, "typeof {}", self.type_query.as_ref().unwrap())
- }
- TsTypeDefKind::TypeRef => {
- let type_ref = self.type_ref.as_ref().unwrap();
- write!(f, "{}", colors::intense_blue(&type_ref.type_name))?;
- if let Some(type_params) = &type_ref.type_params {
- write!(f, "<{}>", SliceDisplayer::new(type_params, ", ", false))?;
- }
- Ok(())
- }
- TsTypeDefKind::Union => {
- let union = self.union.as_ref().unwrap();
- write!(f, "{}", SliceDisplayer::new(union, " | ", false))
- }
- }
- }
-}
-
-pub fn maybe_type_param_instantiation_to_type_defs(
- maybe_type_param_instantiation: Option<&TsTypeParamInstantiation>,
-) -> Vec<TsTypeDef> {
- if let Some(type_param_instantiation) = maybe_type_param_instantiation {
- type_param_instantiation
- .params
- .iter()
- .map(|type_param| type_param.as_ref().into())
- .collect::<Vec<TsTypeDef>>()
- } else {
- vec![]
- }
-}
diff --git a/cli/doc/ts_type_param.rs b/cli/doc/ts_type_param.rs
deleted file mode 100644
index 52ecb74cc..000000000
--- a/cli/doc/ts_type_param.rs
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-use super::ts_type::TsTypeDef;
-use serde::Serialize;
-use std::fmt::{Display, Formatter, Result as FmtResult};
-use swc_ecmascript::ast::TsTypeParam;
-use swc_ecmascript::ast::TsTypeParamDecl;
-
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct TsTypeParamDef {
- pub name: String,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub constraint: Option<TsTypeDef>,
-
- #[serde(skip_serializing_if = "Option::is_none")]
- pub default: Option<TsTypeDef>,
-}
-
-impl Display for TsTypeParamDef {
- fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
- write!(f, "{}", self.name)?;
- if let Some(constraint) = &self.constraint {
- write!(f, " extends {}", constraint)?;
- }
- if let Some(default) = &self.default {
- write!(f, " = {}", default)?;
- }
- Ok(())
- }
-}
-
-impl Into<TsTypeParamDef> for &TsTypeParam {
- fn into(self) -> TsTypeParamDef {
- let name = self.name.sym.to_string();
- let constraint: Option<TsTypeDef> =
- if let Some(ts_type) = self.constraint.as_ref() {
- let type_def: TsTypeDef = (&**ts_type).into();
- Some(type_def)
- } else {
- None
- };
- let default: Option<TsTypeDef> =
- if let Some(ts_type) = self.default.as_ref() {
- let type_def: TsTypeDef = (&**ts_type).into();
- Some(type_def)
- } else {
- None
- };
-
- TsTypeParamDef {
- name,
- constraint,
- default,
- }
- }
-}
-
-pub fn maybe_type_param_decl_to_type_param_defs(
- maybe_type_param_decl: Option<&TsTypeParamDecl>,
-) -> Vec<TsTypeParamDef> {
- if let Some(type_params_decl) = maybe_type_param_decl {
- type_params_decl
- .params
- .iter()
- .map(|type_param| type_param.into())
- .collect::<Vec<TsTypeParamDef>>()
- } else {
- vec![]
- }
-}
diff --git a/cli/doc/type_alias.rs b/cli/doc/type_alias.rs
deleted file mode 100644
index 446e8fbec..000000000
--- a/cli/doc/type_alias.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-use super::parser::DocParser;
-use super::ts_type::TsTypeDef;
-use super::ts_type_param::maybe_type_param_decl_to_type_param_defs;
-use super::ts_type_param::TsTypeParamDef;
-use serde::Serialize;
-
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct TypeAliasDef {
- pub ts_type: TsTypeDef,
- pub type_params: Vec<TsTypeParamDef>,
-}
-
-pub fn get_doc_for_ts_type_alias_decl(
- _doc_parser: &DocParser,
- type_alias_decl: &swc_ecmascript::ast::TsTypeAliasDecl,
-) -> (String, TypeAliasDef) {
- let alias_name = type_alias_decl.id.sym.to_string();
- let ts_type = type_alias_decl.type_ann.as_ref().into();
- let type_params = maybe_type_param_decl_to_type_param_defs(
- type_alias_decl.type_params.as_ref(),
- );
- let type_alias_def = TypeAliasDef {
- ts_type,
- type_params,
- };
-
- (alias_name, type_alias_def)
-}
diff --git a/cli/doc/variable.rs b/cli/doc/variable.rs
deleted file mode 100644
index 4c2fcea14..000000000
--- a/cli/doc/variable.rs
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-use serde::Serialize;
-
-use super::ts_type::ts_type_ann_to_def;
-use super::ts_type::TsTypeDef;
-
-#[derive(Debug, Serialize, Clone)]
-#[serde(rename_all = "camelCase")]
-pub struct VariableDef {
- pub ts_type: Option<TsTypeDef>,
- pub kind: swc_ecmascript::ast::VarDeclKind,
-}
-
-// TODO: change this function to return Vec<(String, VariableDef)> as single
-// var declaration can have multiple declarators
-pub fn get_doc_for_var_decl(
- var_decl: &swc_ecmascript::ast::VarDecl,
-) -> (String, VariableDef) {
- assert!(!var_decl.decls.is_empty());
- let var_declarator = var_decl.decls.get(0).unwrap();
- let var_name = match &var_declarator.name {
- swc_ecmascript::ast::Pat::Ident(ident) => ident.sym.to_string(),
- _ => "<TODO>".to_string(),
- };
-
- let maybe_ts_type = match &var_declarator.name {
- swc_ecmascript::ast::Pat::Ident(ident) => {
- ident.type_ann.as_ref().map(|rt| ts_type_ann_to_def(rt))
- }
- _ => None,
- };
-
- let variable_def = VariableDef {
- ts_type: maybe_ts_type,
- kind: var_decl.kind,
- };
-
- (var_name, variable_def)
-}
diff --git a/cli/global_state.rs b/cli/global_state.rs
index a1d4af86c..daabcf519 100644
--- a/cli/global_state.rs
+++ b/cli/global_state.rs
@@ -313,8 +313,8 @@ fn thread_safe() {
#[test]
fn test_should_allow_js() {
- use crate::doc::Location;
use crate::module_graph::ImportDescriptor;
+ use crate::swc_util::Location;
assert!(should_allow_js(&[
&ModuleGraphFile {
diff --git a/cli/main.rs b/cli/main.rs
index c1774f5b9..353b7763f 100644
--- a/cli/main.rs
+++ b/cli/main.rs
@@ -29,7 +29,6 @@ pub mod deno_dir;
pub mod diagnostics;
mod diff;
mod disk_cache;
-mod doc;
mod file_fetcher;
pub mod flags;
mod flags_allow_net;
@@ -69,14 +68,13 @@ pub mod version;
mod web_worker;
pub mod worker;
-use crate::doc::parser::DocFileLoader;
+use crate::file_fetcher::map_file_extension;
use crate::file_fetcher::SourceFile;
use crate::file_fetcher::SourceFileFetcher;
use crate::file_fetcher::TextDocument;
use crate::fs as deno_fs;
use crate::global_state::GlobalState;
use crate::msg::MediaType;
-use crate::op_error::OpError;
use crate::permissions::Permissions;
use crate::tsc::TargetLib;
use crate::worker::MainWorker;
@@ -85,6 +83,8 @@ use deno_core::Deps;
use deno_core::ErrBox;
use deno_core::EsIsolate;
use deno_core::ModuleSpecifier;
+use deno_doc as doc;
+use deno_doc::parser::DocFileLoader;
use flags::DenoSubcommand;
use flags::Flags;
use futures::future::FutureExt;
@@ -505,19 +505,39 @@ async fn doc_command(
let source_file = source_file.unwrap_or_else(|| "--builtin".to_string());
impl DocFileLoader for SourceFileFetcher {
+ fn resolve(
+ &self,
+ specifier: &str,
+ referrer: &str,
+ ) -> Result<String, doc::DocError> {
+ ModuleSpecifier::resolve_import(specifier, referrer)
+ .map(|specifier| specifier.to_string())
+ .map_err(|e| doc::DocError::Resolve(e.to_string()))
+ }
+
fn load_source_code(
&self,
specifier: &str,
- ) -> Pin<Box<dyn Future<Output = Result<String, OpError>>>> {
+ ) -> Pin<Box<dyn Future<Output = Result<String, doc::DocError>>>> {
let fetcher = self.clone();
- let specifier = specifier.to_string();
+ let specifier = ModuleSpecifier::resolve_url_or_path(specifier)
+ .expect("Expected valid specifier");
async move {
- let specifier = ModuleSpecifier::resolve_url_or_path(&specifier)
- .map_err(OpError::from)?;
let source_file = fetcher
.fetch_source_file(&specifier, None, Permissions::allow_all())
- .await?;
- source_file.source_code.to_string().map_err(OpError::from)
+ .await
+ .map_err(|e| {
+ doc::DocError::Io(std::io::Error::new(
+ std::io::ErrorKind::Other,
+ e.to_string(),
+ ))
+ })?;
+ source_file.source_code.to_string().map_err(|e| {
+ doc::DocError::Io(std::io::Error::new(
+ std::io::ErrorKind::Other,
+ e.to_string(),
+ ))
+ })
}
.boxed_local()
}
@@ -525,14 +545,20 @@ async fn doc_command(
let loader = Box::new(global_state.file_fetcher.clone());
let doc_parser = doc::DocParser::new(loader, private);
+ let media_type = map_file_extension(&PathBuf::from(&source_file));
+ let syntax = swc_util::get_syntax_for_media_type(media_type);
let parse_result = if source_file == "--builtin" {
- doc_parser.parse_source("lib.deno.d.ts", get_types(flags.unstable).as_str())
+ doc_parser.parse_source(
+ "lib.deno.d.ts",
+ syntax,
+ get_types(flags.unstable).as_str(),
+ )
} else {
let module_specifier =
ModuleSpecifier::resolve_url_or_path(&source_file).unwrap();
doc_parser
- .parse_with_reexports(&module_specifier.to_string())
+ .parse_with_reexports(&module_specifier.to_string(), syntax)
.await
};
@@ -555,9 +581,15 @@ async fn doc_command(
eprintln!("Node {} was not found!", filter);
std::process::exit(1);
}
- format!("{}", doc::DocPrinter::new(&nodes, private))
+ format!(
+ "{}",
+ doc::DocPrinter::new(&nodes, colors::use_color(), private)
+ )
} else {
- format!("{}", doc::DocPrinter::new(&doc_nodes, private))
+ format!(
+ "{}",
+ doc::DocPrinter::new(&doc_nodes, colors::use_color(), private)
+ )
};
write_to_stdout_ignore_sigpipe(details.as_bytes()).map_err(ErrBox::from)
diff --git a/cli/module_graph.rs b/cli/module_graph.rs
index 3c07acd3b..5b15c0cd4 100644
--- a/cli/module_graph.rs
+++ b/cli/module_graph.rs
@@ -1,6 +1,5 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use crate::checksum;
-use crate::doc::Location;
use crate::file_fetcher::map_file_extension;
use crate::file_fetcher::SourceFile;
use crate::file_fetcher::SourceFileFetcher;
@@ -8,6 +7,7 @@ use crate::import_map::ImportMap;
use crate::msg::MediaType;
use crate::op_error::OpError;
use crate::permissions::Permissions;
+use crate::swc_util::Location;
use crate::tsc::pre_process_file;
use crate::tsc::ImportDesc;
use crate::tsc::TsReferenceDesc;
diff --git a/cli/swc_util.rs b/cli/swc_util.rs
index d1115e024..13d165113 100644
--- a/cli/swc_util.rs
+++ b/cli/swc_util.rs
@@ -1,6 +1,7 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use crate::msg::MediaType;
use deno_core::ErrBox;
+use serde::Serialize;
use std::error::Error;
use std::fmt;
use std::rc::Rc;
@@ -31,6 +32,31 @@ use swc_ecmascript::transforms::fixer;
use swc_ecmascript::transforms::typescript;
use swc_ecmascript::visit::FoldWith;
+#[derive(Debug, Serialize, Clone, PartialEq)]
+pub struct Location {
+ pub filename: String,
+ pub line: usize,
+ pub col: usize,
+}
+
+impl Into<Location> for swc_common::Loc {
+ fn into(self) -> Location {
+ use swc_common::FileName::*;
+
+ let filename = match &self.file.name {
+ Real(path_buf) => path_buf.to_string_lossy().to_string(),
+ Custom(str_) => str_.to_string(),
+ _ => panic!("invalid filename"),
+ };
+
+ Location {
+ filename,
+ line: self.line,
+ col: self.col_display,
+ }
+ }
+}
+
struct DummyHandler;
impl swc_ecmascript::codegen::Handlers for DummyHandler {}
diff --git a/cli/tsc.rs b/cli/tsc.rs
index f0b2e037b..5fa8b67a3 100644
--- a/cli/tsc.rs
+++ b/cli/tsc.rs
@@ -3,7 +3,6 @@ use crate::colors;
use crate::diagnostics::Diagnostic;
use crate::diagnostics::DiagnosticItem;
use crate::disk_cache::DiskCache;
-use crate::doc::Location;
use crate::file_fetcher::SourceFile;
use crate::file_fetcher::SourceFileFetcher;
use crate::flags::Flags;
@@ -20,6 +19,7 @@ use crate::source_maps::SourceMapGetter;
use crate::startup_data;
use crate::state::State;
use crate::swc_util::AstParser;
+use crate::swc_util::Location;
use crate::swc_util::SwcDiagnosticBuffer;
use crate::version;
use crate::worker::Worker;