summaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
Diffstat (limited to 'cli')
-rw-r--r--cli/doc/class.rs50
-rw-r--r--cli/doc/function.rs43
-rw-r--r--cli/doc/interface.rs101
-rw-r--r--cli/doc/mod.rs3
-rw-r--r--cli/doc/module.rs6
-rw-r--r--cli/doc/node.rs10
-rw-r--r--cli/doc/params.rs83
-rw-r--r--cli/doc/parser.rs5
-rw-r--r--cli/doc/tests.rs244
-rw-r--r--cli/doc/ts_type.rs177
-rw-r--r--cli/doc/ts_type_param.rs57
-rw-r--r--cli/doc/type_alias.rs18
-rw-r--r--cli/doc/variable.rs12
13 files changed, 519 insertions, 290 deletions
diff --git a/cli/doc/class.rs b/cli/doc/class.rs
index 82b6c441c..410789041 100644
--- a/cli/doc/class.rs
+++ b/cli/doc/class.rs
@@ -6,10 +6,15 @@ use serde::Serialize;
use super::function::function_to_function_def;
use super::function::FunctionDef;
+use super::params::assign_pat_to_param_def;
+use super::params::ident_to_param_def;
+use super::params::pat_to_param_def;
use super::parser::DocParser;
use super::ts_type::ts_entity_name_to_name;
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;
@@ -40,8 +45,6 @@ pub struct ClassPropertyDef {
#[serde(rename_all = "camelCase")]
pub struct ClassMethodDef {
pub js_doc: Option<String>,
- // pub ts_type: Option<TsTypeDef>,
- // pub readonly: bool,
pub accessibility: Option<swc_ecma_ast::Accessibility>,
pub is_abstract: bool,
pub is_static: bool,
@@ -54,13 +57,14 @@ pub struct ClassMethodDef {
#[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ClassDef {
- // TODO: decorators, type_params, super_type_params
+ // TODO(bartlomieju): decorators, super_type_params
pub is_abstract: bool,
pub constructors: Vec<ClassConstructorDef>,
pub properties: Vec<ClassPropertyDef>,
pub methods: Vec<ClassMethodDef>,
pub super_class: Option<String>,
pub implements: Vec<String>,
+ pub type_params: Vec<TsTypeParamDef>,
}
fn prop_name_to_string(
@@ -117,31 +121,20 @@ pub fn get_doc_for_class_decl(
let mut params = vec![];
for param in &ctor.params {
- use crate::swc_ecma_ast::Pat;
use crate::swc_ecma_ast::PatOrTsParamProp::*;
let param_def = match param {
- Pat(pat) => match pat {
- Pat::Ident(ident) => {
- let ts_type = ident
- .type_ann
- .as_ref()
- .map(|rt| ts_type_ann_to_def(&doc_parser.source_map, rt));
-
- ParamDef {
- name: ident.sym.to_string(),
- ts_type,
+ Pat(pat) => pat_to_param_def(pat),
+ TsParamProp(ts_param_prop) => {
+ use swc_ecma_ast::TsParamPropParam;
+
+ match &ts_param_prop.param {
+ TsParamPropParam::Ident(ident) => ident_to_param_def(ident),
+ TsParamPropParam::Assign(assign_pat) => {
+ assign_pat_to_param_def(assign_pat)
}
}
- _ => ParamDef {
- name: "<TODO>".to_string(),
- ts_type: None,
- },
- },
- TsParamProp(_) => ParamDef {
- name: "<TODO>".to_string(),
- ts_type: None,
- },
+ }
};
params.push(param_def);
}
@@ -162,8 +155,7 @@ pub fn get_doc_for_class_decl(
let method_js_doc = doc_parser.js_doc_for_span(class_method.span());
let method_name =
prop_name_to_string(&doc_parser.source_map, &class_method.key);
- let fn_def =
- function_to_function_def(doc_parser, &class_method.function);
+ let fn_def = function_to_function_def(&class_method.function);
let method_def = ClassMethodDef {
js_doc: method_js_doc,
accessibility: class_method.accessibility,
@@ -185,7 +177,7 @@ pub fn get_doc_for_class_decl(
let ts_type = class_prop
.type_ann
.as_ref()
- .map(|rt| ts_type_ann_to_def(&doc_parser.source_map, rt));
+ .map(|rt| ts_type_ann_to_def(rt));
use crate::swc_ecma_ast::Expr;
let prop_name = match &*class_prop.key {
@@ -208,13 +200,16 @@ pub fn get_doc_for_class_decl(
};
properties.push(prop_def);
}
- // TODO:
+ // TODO(bartlomieju):
TsIndexSignature(_) => {}
PrivateMethod(_) => {}
PrivateProp(_) => {}
}
}
+ let type_params = maybe_type_param_decl_to_type_param_defs(
+ class_decl.class.type_params.as_ref(),
+ );
let class_name = class_decl.ident.sym.to_string();
let class_def = ClassDef {
is_abstract: class_decl.class.is_abstract,
@@ -223,6 +218,7 @@ pub fn get_doc_for_class_decl(
constructors,
properties,
methods,
+ type_params,
};
(class_name, class_def)
diff --git a/cli/doc/function.rs b/cli/doc/function.rs
index fbfd2d015..4c101ab08 100644
--- a/cli/doc/function.rs
+++ b/cli/doc/function.rs
@@ -1,11 +1,12 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-use crate::swc_ecma_ast;
-use serde::Serialize;
-
-use super::parser::DocParser;
+use super::params::pat_to_param_def;
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 crate::swc_ecma_ast;
+use serde::Serialize;
#[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
@@ -14,57 +15,41 @@ pub struct FunctionDef {
pub return_type: Option<TsTypeDef>,
pub is_async: bool,
pub is_generator: bool,
- // TODO: type_params, decorators
+ pub type_params: Vec<TsTypeParamDef>,
+ // TODO(bartlomieju): decorators
}
pub fn function_to_function_def(
- doc_parser: &DocParser,
function: &swc_ecma_ast::Function,
) -> FunctionDef {
let mut params = vec![];
for param in &function.params {
- use crate::swc_ecma_ast::Pat;
-
- let param_def = match param {
- Pat::Ident(ident) => {
- let ts_type = ident
- .type_ann
- .as_ref()
- .map(|rt| ts_type_ann_to_def(&doc_parser.source_map, rt));
-
- ParamDef {
- name: ident.sym.to_string(),
- ts_type,
- }
- }
- _ => ParamDef {
- name: "<TODO>".to_string(),
- ts_type: None,
- },
- };
-
+ let param_def = pat_to_param_def(param);
params.push(param_def);
}
let maybe_return_type = function
.return_type
.as_ref()
- .map(|rt| ts_type_ann_to_def(&doc_parser.source_map, rt));
+ .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_ecma_ast::FnDecl,
) -> (String, FunctionDef) {
let name = fn_decl.ident.sym.to_string();
- let fn_def = function_to_function_def(doc_parser, &fn_decl.function);
+ let fn_def = function_to_function_def(&fn_decl.function);
(name, fn_def)
}
diff --git a/cli/doc/interface.rs b/cli/doc/interface.rs
index a09bd9c8a..41ef0e720 100644
--- a/cli/doc/interface.rs
+++ b/cli/doc/interface.rs
@@ -2,27 +2,29 @@
use crate::swc_ecma_ast;
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;
#[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct InterfaceMethodDef {
- // TODO: type_params
pub name: String,
pub location: Location,
pub js_doc: Option<String>,
pub params: Vec<ParamDef>,
pub return_type: Option<TsTypeDef>,
+ pub type_params: Vec<TsTypeParamDef>,
}
#[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct InterfacePropertyDef {
- // TODO: type_params
pub name: String,
pub location: Location,
pub js_doc: Option<String>,
@@ -30,25 +32,27 @@ pub struct InterfacePropertyDef {
pub computed: bool,
pub optional: bool,
pub ts_type: Option<TsTypeDef>,
+ pub type_params: Vec<TsTypeParamDef>,
}
#[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct InterfaceCallSignatureDef {
- // TODO: type_params
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 {
- // TODO: extends, type params
+ // TODO(bartlomieju): extends
pub methods: Vec<InterfaceMethodDef>,
pub properties: Vec<InterfacePropertyDef>,
pub call_signatures: Vec<InterfaceCallSignatureDef>,
+ pub type_params: Vec<TsTypeParamDef>,
}
fn expr_to_name(expr: &swc_ecma_ast::Expr) -> String {
@@ -89,26 +93,7 @@ pub fn get_doc_for_ts_interface_decl(
let mut params = vec![];
for param in &ts_method_sig.params {
- use crate::swc_ecma_ast::TsFnParam::*;
-
- let param_def = match param {
- Ident(ident) => {
- let ts_type = ident
- .type_ann
- .as_ref()
- .map(|rt| ts_type_ann_to_def(&doc_parser.source_map, rt));
-
- ParamDef {
- name: ident.sym.to_string(),
- ts_type,
- }
- }
- _ => ParamDef {
- name: "<TODO>".to_string(),
- ts_type: None,
- },
- };
-
+ let param_def = ts_fn_param_to_param_def(param);
params.push(param_def);
}
@@ -117,7 +102,11 @@ pub fn get_doc_for_ts_interface_decl(
let maybe_return_type = ts_method_sig
.type_ann
.as_ref()
- .map(|rt| ts_type_ann_to_def(&doc_parser.source_map, rt));
+ .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,
@@ -128,6 +117,7 @@ pub fn get_doc_for_ts_interface_decl(
.into(),
params,
return_type: maybe_return_type,
+ type_params,
};
methods.push(method_def);
}
@@ -141,33 +131,18 @@ pub fn get_doc_for_ts_interface_decl(
let mut params = vec![];
for param in &ts_prop_sig.params {
- use crate::swc_ecma_ast::TsFnParam::*;
-
- let param_def = match param {
- Ident(ident) => {
- let ts_type = ident
- .type_ann
- .as_ref()
- .map(|rt| ts_type_ann_to_def(&doc_parser.source_map, rt));
-
- ParamDef {
- name: ident.sym.to_string(),
- ts_type,
- }
- }
- _ => ParamDef {
- name: "<TODO>".to_string(),
- ts_type: None,
- },
- };
-
+ let param_def = ts_fn_param_to_param_def(param);
params.push(param_def);
}
let ts_type = ts_prop_sig
.type_ann
.as_ref()
- .map(|rt| ts_type_ann_to_def(&doc_parser.source_map, rt));
+ .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,
@@ -180,6 +155,7 @@ pub fn get_doc_for_ts_interface_decl(
ts_type,
computed: ts_prop_sig.computed,
optional: ts_prop_sig.optional,
+ type_params,
};
properties.push(prop_def);
}
@@ -188,33 +164,18 @@ pub fn get_doc_for_ts_interface_decl(
let mut params = vec![];
for param in &ts_call_sig.params {
- use crate::swc_ecma_ast::TsFnParam::*;
-
- let param_def = match param {
- Ident(ident) => {
- let ts_type = ident
- .type_ann
- .as_ref()
- .map(|rt| ts_type_ann_to_def(&doc_parser.source_map, rt));
-
- ParamDef {
- name: ident.sym.to_string(),
- ts_type,
- }
- }
- _ => ParamDef {
- name: "<TODO>".to_string(),
- ts_type: None,
- },
- };
-
+ let param_def = ts_fn_param_to_param_def(param);
params.push(param_def);
}
let ts_type = ts_call_sig
.type_ann
.as_ref()
- .map(|rt| ts_type_ann_to_def(&doc_parser.source_map, rt));
+ .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,
@@ -224,6 +185,7 @@ pub fn get_doc_for_ts_interface_decl(
.into(),
params,
ts_type,
+ type_params,
};
call_signatures.push(call_sig_def);
}
@@ -233,10 +195,15 @@ pub fn get_doc_for_ts_interface_decl(
}
}
+ let type_params = maybe_type_param_decl_to_type_param_defs(
+ interface_decl.type_params.as_ref(),
+ );
+
let interface_def = InterfaceDef {
methods,
properties,
call_signatures,
+ type_params,
};
(interface_name, interface_def)
diff --git a/cli/doc/mod.rs b/cli/doc/mod.rs
index 4926dccd7..b0f7cf60a 100644
--- a/cli/doc/mod.rs
+++ b/cli/doc/mod.rs
@@ -6,9 +6,11 @@ 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;
@@ -16,6 +18,7 @@ pub use node::DocNode;
pub use node::DocNodeKind;
pub use node::Location;
pub use node::ParamDef;
+pub use node::ParamKind;
pub use parser::DocParser;
#[cfg(test)]
diff --git a/cli/doc/module.rs b/cli/doc/module.rs
index ba62902dc..d2284b36c 100644
--- a/cli/doc/module.rs
+++ b/cli/doc/module.rs
@@ -38,8 +38,7 @@ pub fn get_doc_node_for_export_decl(
}
}
Decl::Fn(fn_decl) => {
- let (name, function_def) =
- super::function::get_doc_for_fn_decl(doc_parser, fn_decl);
+ let (name, function_def) = super::function::get_doc_for_fn_decl(fn_decl);
DocNode {
kind: DocNodeKind::Function,
name,
@@ -55,8 +54,7 @@ pub fn get_doc_node_for_export_decl(
}
}
Decl::Var(var_decl) => {
- let (name, var_def) =
- super::variable::get_doc_for_var_decl(doc_parser, var_decl);
+ let (name, var_def) = super::variable::get_doc_for_var_decl(var_decl);
DocNode {
kind: DocNodeKind::Variable,
name,
diff --git a/cli/doc/node.rs b/cli/doc/node.rs
index 1be3ba7b1..a6b11133e 100644
--- a/cli/doc/node.rs
+++ b/cli/doc/node.rs
@@ -16,8 +16,18 @@ pub enum DocNodeKind {
#[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
+pub enum ParamKind {
+ Identifier,
+ Rest,
+ Array,
+ Object,
+}
+
+#[derive(Debug, Serialize, Clone)]
+#[serde(rename_all = "camelCase")]
pub struct ParamDef {
pub name: String,
+ pub kind: ParamKind,
pub ts_type: Option<super::ts_type::TsTypeDef>,
}
diff --git a/cli/doc/params.rs b/cli/doc/params.rs
new file mode 100644
index 000000000..04fd7f898
--- /dev/null
+++ b/cli/doc/params.rs
@@ -0,0 +1,83 @@
+// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
+use crate::swc_ecma_ast;
+
+use super::ts_type::ts_type_ann_to_def;
+use super::ParamDef;
+use super::ParamKind;
+use crate::swc_ecma_ast::Pat;
+use crate::swc_ecma_ast::TsFnParam;
+
+pub fn ident_to_param_def(ident: &swc_ecma_ast::Ident) -> ParamDef {
+ let ts_type = ident.type_ann.as_ref().map(|rt| ts_type_ann_to_def(rt));
+
+ ParamDef {
+ name: ident.sym.to_string(),
+ kind: ParamKind::Identifier,
+ ts_type,
+ }
+}
+
+fn rest_pat_to_param_def(rest_pat: &swc_ecma_ast::RestPat) -> ParamDef {
+ let name = match &*rest_pat.arg {
+ Pat::Ident(ident) => ident.sym.to_string(),
+ _ => "<TODO>".to_string(),
+ };
+ let ts_type = rest_pat.type_ann.as_ref().map(|rt| ts_type_ann_to_def(rt));
+
+ ParamDef {
+ name,
+ kind: ParamKind::Rest,
+ ts_type,
+ }
+}
+
+fn object_pat_to_param_def(object_pat: &swc_ecma_ast::ObjectPat) -> ParamDef {
+ let ts_type = object_pat
+ .type_ann
+ .as_ref()
+ .map(|rt| ts_type_ann_to_def(rt));
+
+ ParamDef {
+ name: "".to_string(),
+ kind: ParamKind::Object,
+ ts_type,
+ }
+}
+
+fn array_pat_to_param_def(array_pat: &swc_ecma_ast::ArrayPat) -> ParamDef {
+ let ts_type = array_pat.type_ann.as_ref().map(|rt| ts_type_ann_to_def(rt));
+
+ ParamDef {
+ name: "".to_string(),
+ kind: ParamKind::Array,
+ ts_type,
+ }
+}
+
+pub fn assign_pat_to_param_def(
+ assign_pat: &swc_ecma_ast::AssignPat,
+) -> ParamDef {
+ pat_to_param_def(&*assign_pat.left)
+}
+
+pub fn pat_to_param_def(pat: &swc_ecma_ast::Pat) -> ParamDef {
+ match pat {
+ Pat::Ident(ident) => ident_to_param_def(ident),
+ Pat::Array(array_pat) => array_pat_to_param_def(array_pat),
+ Pat::Rest(rest_pat) => rest_pat_to_param_def(rest_pat),
+ Pat::Object(object_pat) => object_pat_to_param_def(object_pat),
+ Pat::Assign(assign_pat) => assign_pat_to_param_def(assign_pat),
+ _ => unreachable!(),
+ }
+}
+
+pub fn ts_fn_param_to_param_def(
+ ts_fn_param: &swc_ecma_ast::TsFnParam,
+) -> ParamDef {
+ match ts_fn_param {
+ TsFnParam::Ident(ident) => ident_to_param_def(ident),
+ TsFnParam::Array(array_pat) => array_pat_to_param_def(array_pat),
+ TsFnParam::Rest(rest_pat) => rest_pat_to_param_def(rest_pat),
+ TsFnParam::Object(object_pat) => object_pat_to_param_def(object_pat),
+ }
+}
diff --git a/cli/doc/parser.rs b/cli/doc/parser.rs
index 7c67f8d09..4b37c5fae 100644
--- a/cli/doc/parser.rs
+++ b/cli/doc/parser.rs
@@ -347,7 +347,7 @@ impl DocParser {
return None;
}
let (name, function_def) =
- super::function::get_doc_for_fn_decl(self, fn_decl);
+ super::function::get_doc_for_fn_decl(fn_decl);
let (js_doc, location) = self.details_for_span(fn_decl.function.span);
Some(DocNode {
kind: DocNodeKind::Function,
@@ -367,8 +367,7 @@ impl DocParser {
if !var_decl.declare {
return None;
}
- let (name, var_def) =
- super::variable::get_doc_for_var_decl(self, var_decl);
+ 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 {
kind: DocNodeKind::Variable,
diff --git a/cli/doc/tests.rs b/cli/doc/tests.rs
index 337f32466..fb2c69689 100644
--- a/cli/doc/tests.rs
+++ b/cli/doc/tests.rs
@@ -52,7 +52,7 @@ async fn export_fn() {
*
* Or not that many?
*/
-export function foo(a: string, b: number): void {
+export function foo(a: string, b: number, cb: (...cbArgs: unknown[]) => void, ...args: unknown[]): void {
console.log("Hello world");
}
"#;
@@ -65,9 +65,11 @@ export function foo(a: string, b: number): void {
"functionDef": {
"isAsync": false,
"isGenerator": false,
+ "typeParams": [],
"params": [
{
"name": "a",
+ "kind": "identifier",
"tsType": {
"keyword": "string",
"kind": "keyword",
@@ -76,12 +78,56 @@ export function foo(a: string, b: number): void {
},
{
"name": "b",
+ "kind": "identifier",
"tsType": {
"keyword": "number",
"kind": "keyword",
"repr": "number",
},
},
+ {
+ "name": "cb",
+ "kind": "identifier",
+ "tsType": {
+ "repr": "",
+ "kind": "fnOrConstructor",
+ "fnOrConstructor": {
+ "constructor": false,
+ "tsType": {
+ "keyword": "void",
+ "kind": "keyword",
+ "repr": "void"
+ },
+ "typeParams": [],
+ "params": [{
+ "kind": "rest",
+ "name": "cbArgs",
+ "tsType": {
+ "repr": "",
+ "kind": "array",
+ "array": {
+ "repr": "unknown",
+ "kind": "keyword",
+ "keyword": "unknown"
+ }
+ },
+ }]
+ }
+ },
+ },
+ {
+ "name": "args",
+ "kind": "rest",
+ "tsType": {
+ "repr": "",
+ "kind": "array",
+ "array": {
+ "repr": "unknown",
+ "kind": "keyword",
+ "keyword": "unknown"
+ }
+ }
+ }
],
"returnType": {
"keyword": "void",
@@ -98,6 +144,7 @@ export function foo(a: string, b: number): void {
},
"name": "foo",
});
+
let actual = serde_json::to_value(entry).unwrap();
assert_eq!(actual, expected_json);
@@ -108,6 +155,85 @@ export function foo(a: string, b: number): void {
}
#[tokio::test]
+async fn export_fn2() {
+ let source_code = 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");
+}
+"#;
+ let loader =
+ TestLoader::new(vec![("test.ts".to_string(), source_code.to_string())]);
+ let entries = DocParser::new(loader).parse("test.ts").await.unwrap();
+ assert_eq!(entries.len(), 1);
+ let entry = &entries[0];
+ let expected_json = json!({
+ "functionDef": {
+ "isAsync": false,
+ "isGenerator": false,
+ "typeParams": [],
+ "params": [
+ {
+ "name": "",
+ "kind": "array",
+ "tsType": {
+ "repr": "",
+ "kind": "array",
+ "array": {
+ "repr": "number",
+ "kind": "keyword",
+ "keyword": "number"
+ }
+ }
+ },
+ {
+ "name": "",
+ "kind": "object",
+ "tsType": null
+ },
+ {
+ "name": "ops",
+ "kind": "identifier",
+ "tsType": {
+ "repr": "AssignOpts",
+ "kind": "typeRef",
+ "typeRef": {
+ "typeName": "AssignOpts",
+ "typeParams": null,
+ }
+ }
+ },
+ ],
+ "returnType": {
+ "keyword": "void",
+ "kind": "keyword",
+ "repr": "void",
+ },
+ },
+ "jsDoc": null,
+ "kind": "function",
+ "location": {
+ "col": 0,
+ "filename": "test.ts",
+ "line": 7,
+ },
+ "name": "foo",
+ });
+
+ let actual = serde_json::to_value(entry).unwrap();
+ assert_eq!(actual, expected_json);
+
+ assert!(
+ colors::strip_ansi_codes(super::printer::format(entries).as_str())
+ .contains("foo")
+ );
+}
+
+#[tokio::test]
async fn export_const() {
let source_code =
"/** Something about fizzBuzz */\nexport const fizzBuzz = \"fizzBuzz\";\n";
@@ -180,6 +306,7 @@ export class Foobar extends Fizz implements Buzz, Aldrin {
"isAbstract": false,
"superClass": "Fizz",
"implements": ["Buzz", "Aldrin"],
+ "typeParams": [],
"constructors": [
{
"jsDoc": "Constructor js doc",
@@ -188,6 +315,7 @@ export class Foobar extends Fizz implements Buzz, Aldrin {
"params": [
{
"name": "name",
+ "kind": "identifier",
"tsType": {
"repr": "string",
"kind": "keyword",
@@ -195,12 +323,22 @@ export class Foobar extends Fizz implements Buzz, Aldrin {
}
},
{
- "name": "<TODO>",
- "tsType": null
+ "name": "private2",
+ "kind": "identifier",
+ "tsType": {
+ "repr": "number",
+ "kind": "keyword",
+ "keyword": "number"
+ }
},
{
- "name": "<TODO>",
- "tsType": null
+ "name": "protected2",
+ "kind": "identifier",
+ "tsType": {
+ "repr": "number",
+ "kind": "keyword",
+ "keyword": "number"
+ }
}
],
"location": {
@@ -308,6 +446,7 @@ export class Foobar extends Fizz implements Buzz, Aldrin {
"typeName": "Promise"
}
},
+ "typeParams": [],
"isAsync": true,
"isGenerator": false
},
@@ -326,20 +465,21 @@ export class Foobar extends Fizz implements Buzz, Aldrin {
"kind": "method",
"functionDef": {
"params": [],
- "returnType": {
- "repr": "void",
- "kind": "keyword",
- "keyword": "void"
- },
- "isAsync": false,
- "isGenerator": false
+ "returnType": {
+ "repr": "void",
+ "kind": "keyword",
+ "keyword": "void"
},
- "location": {
- "filename": "test.ts",
- "line": 18,
- "col": 4
- }
+ "isAsync": false,
+ "isGenerator": false,
+ "typeParams": []
+ },
+ "location": {
+ "filename": "test.ts",
+ "line": 18,
+ "col": 4
}
+ }
]
}
});
@@ -391,6 +531,7 @@ export interface Reader {
"params": [
{
"name": "buf",
+ "kind": "identifier",
"tsType": {
"repr": "Uint8Array",
"kind": "typeRef",
@@ -402,6 +543,7 @@ export interface Reader {
},
{
"name": "something",
+ "kind": "identifier",
"tsType": {
"repr": "unknown",
"kind": "keyword",
@@ -409,6 +551,7 @@ export interface Reader {
}
}
],
+ "typeParams": [],
"returnType": {
"repr": "Promise",
"kind": "typeRef",
@@ -426,7 +569,8 @@ export interface Reader {
}
],
"properties": [],
- "callSignatures": []
+ "callSignatures": [],
+ "typeParams": [],
}
});
let actual = serde_json::to_value(entry).unwrap();
@@ -439,6 +583,65 @@ export interface Reader {
}
#[tokio::test]
+async fn export_interface2() {
+ let source_code = r#"
+export interface TypedIface<T> {
+ something(): T
+}
+ "#;
+ let loader =
+ TestLoader::new(vec![("test.ts".to_string(), source_code.to_string())]);
+ let entries = DocParser::new(loader).parse("test.ts").await.unwrap();
+ assert_eq!(entries.len(), 1);
+ let entry = &entries[0];
+ let expected_json = json!({
+ "kind": "interface",
+ "name": "TypedIface",
+ "location": {
+ "filename": "test.ts",
+ "line": 2,
+ "col": 0
+ },
+ "jsDoc": null,
+ "interfaceDef": {
+ "methods": [
+ {
+ "name": "something",
+ "location": {
+ "filename": "test.ts",
+ "line": 3,
+ "col": 4
+ },
+ "jsDoc": null,
+ "params": [],
+ "typeParams": [],
+ "returnType": {
+ "repr": "T",
+ "kind": "typeRef",
+ "typeRef": {
+ "typeParams": null,
+ "typeName": "T"
+ }
+ }
+ }
+ ],
+ "properties": [],
+ "callSignatures": [],
+ "typeParams": [
+ { "name": "T" }
+ ],
+ }
+ });
+ let actual = serde_json::to_value(entry).unwrap();
+ assert_eq!(actual, expected_json);
+
+ assert!(
+ colors::strip_ansi_codes(super::printer::format(entries).as_str())
+ .contains("interface TypedIface")
+ );
+}
+
+#[tokio::test]
async fn export_type_alias() {
let source_code = r#"
/** Array holding numbers */
@@ -459,6 +662,7 @@ export type NumberArray = Array<number>;
},
"jsDoc": "Array holding numbers",
"typeAliasDef": {
+ "typeParams": [],
"tsType": {
"repr": "Array",
"kind": "typeRef",
@@ -751,6 +955,7 @@ async fn optional_return_type() {
"params": [
{
"name": "a",
+ "kind": "identifier",
"tsType": {
"keyword": "number",
"kind": "keyword",
@@ -758,6 +963,7 @@ async fn optional_return_type() {
},
}
],
+ "typeParams": [],
"returnType": null,
"isAsync": false,
"isGenerator": false
@@ -841,6 +1047,7 @@ export function fooFn(a: number) {
"params": [
{
"name": "a",
+ "kind": "identifier",
"tsType": {
"keyword": "number",
"kind": "keyword",
@@ -848,6 +1055,7 @@ export function fooFn(a: number) {
},
}
],
+ "typeParams": [],
"returnType": null,
"isAsync": false,
"isGenerator": false
diff --git a/cli/doc/ts_type.rs b/cli/doc/ts_type.rs
index 9590c7e60..8359f64cc 100644
--- a/cli/doc/ts_type.rs
+++ b/cli/doc/ts_type.rs
@@ -1,6 +1,8 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
+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::swc_common::SourceMap;
use crate::swc_ecma_ast;
use crate::swc_ecma_ast::TsArrayType;
use crate::swc_ecma_ast::TsConditionalType;
@@ -36,12 +38,12 @@ use serde::Serialize;
// * TsRestType(TsRestType),
// * TsUnionOrIntersectionType(TsUnionOrIntersectionType),
// * TsConditionalType(TsConditionalType),
-// TsInferType(TsInferType),
// * TsParenthesizedType(TsParenthesizedType),
// * TsTypeOperator(TsTypeOperator),
// * TsIndexedAccessType(TsIndexedAccessType),
-// TsMappedType(TsMappedType),
// * TsLitType(TsLitType),
+// TsInferType(TsInferType),
+// TsMappedType(TsMappedType),
// TsTypePredicate(TsTypePredicate),
// TsImportType(TsImportType),
// }
@@ -340,24 +342,7 @@ impl Into<TsTypeDef> for &TsTypeLit {
let mut params = vec![];
for param in &ts_method_sig.params {
- use crate::swc_ecma_ast::TsFnParam::*;
-
- let param_def = match param {
- Ident(ident) => {
- let ts_type =
- ident.type_ann.as_ref().map(|rt| (&*rt.type_ann).into());
-
- ParamDef {
- name: ident.sym.to_string(),
- ts_type,
- }
- }
- _ => ParamDef {
- name: "<TODO>".to_string(),
- ts_type: None,
- },
- };
-
+ let param_def = ts_fn_param_to_param_def(param);
params.push(param_def);
}
@@ -366,10 +351,14 @@ impl Into<TsTypeDef> for &TsTypeLit {
.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 method_def = LiteralMethodDef {
name: "<TODO>".to_string(),
params,
return_type: maybe_return_type,
+ type_params,
};
methods.push(method_def);
}
@@ -382,24 +371,7 @@ impl Into<TsTypeDef> for &TsTypeLit {
let mut params = vec![];
for param in &ts_prop_sig.params {
- use crate::swc_ecma_ast::TsFnParam::*;
-
- let param_def = match param {
- Ident(ident) => {
- let ts_type =
- ident.type_ann.as_ref().map(|rt| (&*rt.type_ann).into());
-
- ParamDef {
- name: ident.sym.to_string(),
- ts_type,
- }
- }
- _ => ParamDef {
- name: "<TODO>".to_string(),
- ts_type: None,
- },
- };
-
+ let param_def = ts_fn_param_to_param_def(param);
params.push(param_def);
}
@@ -408,36 +380,23 @@ impl Into<TsTypeDef> for &TsTypeLit {
.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 {
- use crate::swc_ecma_ast::TsFnParam::*;
-
- let param_def = match param {
- Ident(ident) => {
- let ts_type =
- ident.type_ann.as_ref().map(|rt| (&*rt.type_ann).into());
-
- ParamDef {
- name: ident.sym.to_string(),
- ts_type,
- }
- }
- _ => ParamDef {
- name: "<TODO>".to_string(),
- ts_type: None,
- },
- };
-
+ let param_def = ts_fn_param_to_param_def(param);
params.push(param_def);
}
@@ -446,7 +405,15 @@ impl Into<TsTypeDef> for &TsTypeLit {
.as_ref()
.map(|rt| (&*rt.type_ann).into());
- let call_sig_def = LiteralCallSignatureDef { params, ts_type };
+ 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);
}
// TODO:
@@ -495,68 +462,37 @@ impl Into<TsTypeDef> for &TsFnOrConstructorType {
let mut params = vec![];
for param in &ts_fn_type.params {
- use crate::swc_ecma_ast::TsFnParam::*;
-
- let param_def = match param {
- Ident(ident) => {
- let ts_type: Option<TsTypeDef> =
- ident.type_ann.as_ref().map(|rt| {
- let type_box = &*rt.type_ann;
- (&*type_box).into()
- });
-
- ParamDef {
- name: ident.sym.to_string(),
- ts_type,
- }
- }
- _ => ParamDef {
- name: "<TODO>".to_string(),
- ts_type: None,
- },
- };
-
+ let param_def = ts_fn_param_to_param_def(param);
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_fn_type.type_ann.type_ann).into(),
+ 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 {
- use crate::swc_ecma_ast::TsFnParam::*;
-
- let param_def = match param {
- Ident(ident) => {
- let ts_type: Option<TsTypeDef> =
- ident.type_ann.as_ref().map(|rt| {
- let type_box = &*rt.type_ann;
- (&*type_box).into()
- });
-
- ParamDef {
- name: ident.sym.to_string(),
- ts_type,
- }
- }
- _ => ParamDef {
- name: "<TODO>".to_string(),
- ts_type: None,
- },
- };
-
+ let param_def = ts_fn_param_to_param_def(param);
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: (&*ctor_type.type_ann.type_ann).into(),
- params: vec![],
+ ts_type: ts_type_ann_to_def(&ctor_type.type_ann),
+ params,
+ type_params,
}
}
};
@@ -638,10 +574,10 @@ pub struct TsTypeOperatorDef {
#[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct TsFnOrConstructorDef {
- // TODO: type_params
pub constructor: bool,
pub ts_type: TsTypeDef,
pub params: Vec<ParamDef>,
+ pub type_params: Vec<TsTypeParamDef>,
}
#[derive(Debug, Serialize, Clone)]
@@ -664,35 +600,29 @@ pub struct TsIndexedAccessDef {
#[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct LiteralMethodDef {
- // TODO: type_params
pub name: String,
- // pub location: Location,
- // pub js_doc: Option<String>,
pub params: Vec<ParamDef>,
pub return_type: Option<TsTypeDef>,
+ pub type_params: Vec<TsTypeParamDef>,
}
#[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct LiteralPropertyDef {
- // TODO: type_params
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>,
}
#[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct LiteralCallSignatureDef {
- // TODO: type_params
- // 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)]
@@ -732,7 +662,6 @@ pub struct TsTypeDef {
pub kind: Option<TsTypeDefKind>,
- // TODO: make this struct more conrete
#[serde(skip_serializing_if = "Option::is_none")]
pub keyword: Option<String>,
@@ -785,10 +714,7 @@ pub struct TsTypeDef {
pub type_literal: Option<TsTypeLiteralDef>,
}
-pub fn ts_type_ann_to_def(
- source_map: &SourceMap,
- type_ann: &TsTypeAnn,
-) -> TsTypeDef {
+pub fn ts_type_ann_to_def(type_ann: &TsTypeAnn) -> TsTypeDef {
use crate::swc_ecma_ast::TsType::*;
match &*type_ann.type_ann {
@@ -808,16 +734,9 @@ pub fn ts_type_ann_to_def(
TsConditionalType(conditional_type) => conditional_type.into(),
TsIndexedAccessType(indexed_access_type) => indexed_access_type.into(),
TsTypeLit(type_literal) => type_literal.into(),
- _ => {
- let repr = source_map
- .span_to_snippet(type_ann.span)
- .expect("Class prop type not found");
- let repr = repr.trim_start_matches(':').trim_start().to_string();
-
- TsTypeDef {
- repr,
- ..Default::default()
- }
- }
+ _ => TsTypeDef {
+ repr: "<TODO>".to_string(),
+ ..Default::default()
+ },
}
}
diff --git a/cli/doc/ts_type_param.rs b/cli/doc/ts_type_param.rs
new file mode 100644
index 000000000..4edb7dee1
--- /dev/null
+++ b/cli/doc/ts_type_param.rs
@@ -0,0 +1,57 @@
+// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
+use super::ts_type::TsTypeDef;
+use crate::swc_ecma_ast::TsTypeParam;
+use crate::swc_ecma_ast::TsTypeParamDecl;
+use serde::Serialize;
+
+#[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 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
index ad9933978..b26395c3f 100644
--- a/cli/doc/type_alias.rs
+++ b/cli/doc/type_alias.rs
@@ -1,15 +1,16 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-use crate::swc_ecma_ast;
-use serde::Serialize;
-
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 crate::swc_ecma_ast;
+use serde::Serialize;
#[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct TypeAliasDef {
pub ts_type: TsTypeDef,
- // TODO: type_params
+ pub type_params: Vec<TsTypeParamDef>,
}
pub fn get_doc_for_ts_type_alias_decl(
@@ -18,8 +19,13 @@ pub fn get_doc_for_ts_type_alias_decl(
) -> (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_alias_def = TypeAliasDef { ts_type };
+ 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
index b8ebcfd72..e7bc475d1 100644
--- a/cli/doc/variable.rs
+++ b/cli/doc/variable.rs
@@ -2,7 +2,6 @@
use crate::swc_ecma_ast;
use serde::Serialize;
-use super::parser::DocParser;
use super::ts_type::ts_type_ann_to_def;
use super::ts_type::TsTypeDef;
@@ -13,12 +12,12 @@ pub struct VariableDef {
pub kind: swc_ecma_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(
- doc_parser: &DocParser,
var_decl: &swc_ecma_ast::VarDecl,
) -> (String, VariableDef) {
assert!(!var_decl.decls.is_empty());
- // TODO: support multiple declarators
let var_declarator = var_decl.decls.get(0).unwrap();
let var_name = match &var_declarator.name {
@@ -27,10 +26,9 @@ pub fn get_doc_for_var_decl(
};
let maybe_ts_type = match &var_declarator.name {
- swc_ecma_ast::Pat::Ident(ident) => ident
- .type_ann
- .as_ref()
- .map(|rt| ts_type_ann_to_def(&doc_parser.source_map, rt)),
+ swc_ecma_ast::Pat::Ident(ident) => {
+ ident.type_ann.as_ref().map(|rt| ts_type_ann_to_def(rt))
+ }
_ => None,
};