feat(doc): handle function params and type params (#4672)

This commit is contained in:
Bartek Iwańczuk 2020-04-08 17:03:42 +02:00 committed by GitHub
parent fe17496831
commit 491b8e1cea
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 518 additions and 289 deletions

View file

@ -6,10 +6,15 @@ use serde::Serialize;
use super::function::function_to_function_def; use super::function::function_to_function_def;
use super::function::FunctionDef; 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::parser::DocParser;
use super::ts_type::ts_entity_name_to_name; use super::ts_type::ts_entity_name_to_name;
use super::ts_type::ts_type_ann_to_def; use super::ts_type::ts_type_ann_to_def;
use super::ts_type::TsTypeDef; 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::Location;
use super::ParamDef; use super::ParamDef;
@ -40,8 +45,6 @@ pub struct ClassPropertyDef {
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ClassMethodDef { pub struct ClassMethodDef {
pub js_doc: Option<String>, pub js_doc: Option<String>,
// pub ts_type: Option<TsTypeDef>,
// pub readonly: bool,
pub accessibility: Option<swc_ecma_ast::Accessibility>, pub accessibility: Option<swc_ecma_ast::Accessibility>,
pub is_abstract: bool, pub is_abstract: bool,
pub is_static: bool, pub is_static: bool,
@ -54,13 +57,14 @@ pub struct ClassMethodDef {
#[derive(Debug, Serialize, Clone)] #[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ClassDef { pub struct ClassDef {
// TODO: decorators, type_params, super_type_params // TODO(bartlomieju): decorators, super_type_params
pub is_abstract: bool, pub is_abstract: bool,
pub constructors: Vec<ClassConstructorDef>, pub constructors: Vec<ClassConstructorDef>,
pub properties: Vec<ClassPropertyDef>, pub properties: Vec<ClassPropertyDef>,
pub methods: Vec<ClassMethodDef>, pub methods: Vec<ClassMethodDef>,
pub super_class: Option<String>, pub super_class: Option<String>,
pub implements: Vec<String>, pub implements: Vec<String>,
pub type_params: Vec<TsTypeParamDef>,
} }
fn prop_name_to_string( fn prop_name_to_string(
@ -117,31 +121,20 @@ pub fn get_doc_for_class_decl(
let mut params = vec![]; let mut params = vec![];
for param in &ctor.params { for param in &ctor.params {
use crate::swc_ecma_ast::Pat;
use crate::swc_ecma_ast::PatOrTsParamProp::*; use crate::swc_ecma_ast::PatOrTsParamProp::*;
let param_def = match param { let param_def = match param {
Pat(pat) => match pat { Pat(pat) => pat_to_param_def(pat),
Pat::Ident(ident) => { TsParamProp(ts_param_prop) => {
let ts_type = ident use swc_ecma_ast::TsParamPropParam;
.type_ann
.as_ref()
.map(|rt| ts_type_ann_to_def(&doc_parser.source_map, rt));
ParamDef { match &ts_param_prop.param {
name: ident.sym.to_string(), TsParamPropParam::Ident(ident) => ident_to_param_def(ident),
ts_type, 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); 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_js_doc = doc_parser.js_doc_for_span(class_method.span());
let method_name = let method_name =
prop_name_to_string(&doc_parser.source_map, &class_method.key); prop_name_to_string(&doc_parser.source_map, &class_method.key);
let fn_def = let fn_def = function_to_function_def(&class_method.function);
function_to_function_def(doc_parser, &class_method.function);
let method_def = ClassMethodDef { let method_def = ClassMethodDef {
js_doc: method_js_doc, js_doc: method_js_doc,
accessibility: class_method.accessibility, accessibility: class_method.accessibility,
@ -185,7 +177,7 @@ pub fn get_doc_for_class_decl(
let ts_type = class_prop let ts_type = class_prop
.type_ann .type_ann
.as_ref() .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; use crate::swc_ecma_ast::Expr;
let prop_name = match &*class_prop.key { let prop_name = match &*class_prop.key {
@ -208,13 +200,16 @@ pub fn get_doc_for_class_decl(
}; };
properties.push(prop_def); properties.push(prop_def);
} }
// TODO: // TODO(bartlomieju):
TsIndexSignature(_) => {} TsIndexSignature(_) => {}
PrivateMethod(_) => {} PrivateMethod(_) => {}
PrivateProp(_) => {} 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_name = class_decl.ident.sym.to_string();
let class_def = ClassDef { let class_def = ClassDef {
is_abstract: class_decl.class.is_abstract, is_abstract: class_decl.class.is_abstract,
@ -223,6 +218,7 @@ pub fn get_doc_for_class_decl(
constructors, constructors,
properties, properties,
methods, methods,
type_params,
}; };
(class_name, class_def) (class_name, class_def)

View file

@ -1,11 +1,12 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use crate::swc_ecma_ast; use super::params::pat_to_param_def;
use serde::Serialize;
use super::parser::DocParser;
use super::ts_type::ts_type_ann_to_def; use super::ts_type::ts_type_ann_to_def;
use super::ts_type::TsTypeDef; 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 super::ParamDef;
use crate::swc_ecma_ast;
use serde::Serialize;
#[derive(Debug, Serialize, Clone)] #[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
@ -14,57 +15,41 @@ pub struct FunctionDef {
pub return_type: Option<TsTypeDef>, pub return_type: Option<TsTypeDef>,
pub is_async: bool, pub is_async: bool,
pub is_generator: bool, pub is_generator: bool,
// TODO: type_params, decorators pub type_params: Vec<TsTypeParamDef>,
// TODO(bartlomieju): decorators
} }
pub fn function_to_function_def( pub fn function_to_function_def(
doc_parser: &DocParser,
function: &swc_ecma_ast::Function, function: &swc_ecma_ast::Function,
) -> FunctionDef { ) -> FunctionDef {
let mut params = vec![]; let mut params = vec![];
for param in &function.params { for param in &function.params {
use crate::swc_ecma_ast::Pat; let param_def = pat_to_param_def(param);
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,
},
};
params.push(param_def); params.push(param_def);
} }
let maybe_return_type = function let maybe_return_type = function
.return_type .return_type
.as_ref() .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 { FunctionDef {
params, params,
return_type: maybe_return_type, return_type: maybe_return_type,
is_async: function.is_async, is_async: function.is_async,
is_generator: function.is_generator, is_generator: function.is_generator,
type_params,
} }
} }
pub fn get_doc_for_fn_decl( pub fn get_doc_for_fn_decl(
doc_parser: &DocParser,
fn_decl: &swc_ecma_ast::FnDecl, fn_decl: &swc_ecma_ast::FnDecl,
) -> (String, FunctionDef) { ) -> (String, FunctionDef) {
let name = fn_decl.ident.sym.to_string(); 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) (name, fn_def)
} }

View file

@ -2,27 +2,29 @@
use crate::swc_ecma_ast; use crate::swc_ecma_ast;
use serde::Serialize; use serde::Serialize;
use super::params::ts_fn_param_to_param_def;
use super::parser::DocParser; use super::parser::DocParser;
use super::ts_type::ts_type_ann_to_def; use super::ts_type::ts_type_ann_to_def;
use super::ts_type::TsTypeDef; 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::Location;
use super::ParamDef; use super::ParamDef;
#[derive(Debug, Serialize, Clone)] #[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct InterfaceMethodDef { pub struct InterfaceMethodDef {
// TODO: type_params
pub name: String, pub name: String,
pub location: Location, pub location: Location,
pub js_doc: Option<String>, pub js_doc: Option<String>,
pub params: Vec<ParamDef>, pub params: Vec<ParamDef>,
pub return_type: Option<TsTypeDef>, pub return_type: Option<TsTypeDef>,
pub type_params: Vec<TsTypeParamDef>,
} }
#[derive(Debug, Serialize, Clone)] #[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct InterfacePropertyDef { pub struct InterfacePropertyDef {
// TODO: type_params
pub name: String, pub name: String,
pub location: Location, pub location: Location,
pub js_doc: Option<String>, pub js_doc: Option<String>,
@ -30,25 +32,27 @@ pub struct InterfacePropertyDef {
pub computed: bool, pub computed: bool,
pub optional: bool, pub optional: bool,
pub ts_type: Option<TsTypeDef>, pub ts_type: Option<TsTypeDef>,
pub type_params: Vec<TsTypeParamDef>,
} }
#[derive(Debug, Serialize, Clone)] #[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct InterfaceCallSignatureDef { pub struct InterfaceCallSignatureDef {
// TODO: type_params
pub location: Location, pub location: Location,
pub js_doc: Option<String>, pub js_doc: Option<String>,
pub params: Vec<ParamDef>, pub params: Vec<ParamDef>,
pub ts_type: Option<TsTypeDef>, pub ts_type: Option<TsTypeDef>,
pub type_params: Vec<TsTypeParamDef>,
} }
#[derive(Debug, Serialize, Clone)] #[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct InterfaceDef { pub struct InterfaceDef {
// TODO: extends, type params // TODO(bartlomieju): extends
pub methods: Vec<InterfaceMethodDef>, pub methods: Vec<InterfaceMethodDef>,
pub properties: Vec<InterfacePropertyDef>, pub properties: Vec<InterfacePropertyDef>,
pub call_signatures: Vec<InterfaceCallSignatureDef>, pub call_signatures: Vec<InterfaceCallSignatureDef>,
pub type_params: Vec<TsTypeParamDef>,
} }
fn expr_to_name(expr: &swc_ecma_ast::Expr) -> String { 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![]; let mut params = vec![];
for param in &ts_method_sig.params { for param in &ts_method_sig.params {
use crate::swc_ecma_ast::TsFnParam::*; let param_def = ts_fn_param_to_param_def(param);
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,
},
};
params.push(param_def); params.push(param_def);
} }
@ -117,7 +102,11 @@ pub fn get_doc_for_ts_interface_decl(
let maybe_return_type = ts_method_sig let maybe_return_type = ts_method_sig
.type_ann .type_ann
.as_ref() .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 { let method_def = InterfaceMethodDef {
name, name,
@ -128,6 +117,7 @@ pub fn get_doc_for_ts_interface_decl(
.into(), .into(),
params, params,
return_type: maybe_return_type, return_type: maybe_return_type,
type_params,
}; };
methods.push(method_def); methods.push(method_def);
} }
@ -141,33 +131,18 @@ pub fn get_doc_for_ts_interface_decl(
let mut params = vec![]; let mut params = vec![];
for param in &ts_prop_sig.params { for param in &ts_prop_sig.params {
use crate::swc_ecma_ast::TsFnParam::*; let param_def = ts_fn_param_to_param_def(param);
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,
},
};
params.push(param_def); params.push(param_def);
} }
let ts_type = ts_prop_sig let ts_type = ts_prop_sig
.type_ann .type_ann
.as_ref() .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 { let prop_def = InterfacePropertyDef {
name, name,
@ -180,6 +155,7 @@ pub fn get_doc_for_ts_interface_decl(
ts_type, ts_type,
computed: ts_prop_sig.computed, computed: ts_prop_sig.computed,
optional: ts_prop_sig.optional, optional: ts_prop_sig.optional,
type_params,
}; };
properties.push(prop_def); properties.push(prop_def);
} }
@ -188,33 +164,18 @@ pub fn get_doc_for_ts_interface_decl(
let mut params = vec![]; let mut params = vec![];
for param in &ts_call_sig.params { for param in &ts_call_sig.params {
use crate::swc_ecma_ast::TsFnParam::*; let param_def = ts_fn_param_to_param_def(param);
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,
},
};
params.push(param_def); params.push(param_def);
} }
let ts_type = ts_call_sig let ts_type = ts_call_sig
.type_ann .type_ann
.as_ref() .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 { let call_sig_def = InterfaceCallSignatureDef {
js_doc: call_sig_js_doc, js_doc: call_sig_js_doc,
@ -224,6 +185,7 @@ pub fn get_doc_for_ts_interface_decl(
.into(), .into(),
params, params,
ts_type, ts_type,
type_params,
}; };
call_signatures.push(call_sig_def); 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 { let interface_def = InterfaceDef {
methods, methods,
properties, properties,
call_signatures, call_signatures,
type_params,
}; };
(interface_name, interface_def) (interface_name, interface_def)

View file

@ -6,9 +6,11 @@ pub mod interface;
pub mod module; pub mod module;
pub mod namespace; pub mod namespace;
mod node; mod node;
pub mod params;
pub mod parser; pub mod parser;
pub mod printer; pub mod printer;
pub mod ts_type; pub mod ts_type;
pub mod ts_type_param;
pub mod type_alias; pub mod type_alias;
pub mod variable; pub mod variable;
@ -16,6 +18,7 @@ pub use node::DocNode;
pub use node::DocNodeKind; pub use node::DocNodeKind;
pub use node::Location; pub use node::Location;
pub use node::ParamDef; pub use node::ParamDef;
pub use node::ParamKind;
pub use parser::DocParser; pub use parser::DocParser;
#[cfg(test)] #[cfg(test)]

View file

@ -38,8 +38,7 @@ pub fn get_doc_node_for_export_decl(
} }
} }
Decl::Fn(fn_decl) => { Decl::Fn(fn_decl) => {
let (name, function_def) = let (name, function_def) = super::function::get_doc_for_fn_decl(fn_decl);
super::function::get_doc_for_fn_decl(doc_parser, fn_decl);
DocNode { DocNode {
kind: DocNodeKind::Function, kind: DocNodeKind::Function,
name, name,
@ -55,8 +54,7 @@ pub fn get_doc_node_for_export_decl(
} }
} }
Decl::Var(var_decl) => { Decl::Var(var_decl) => {
let (name, var_def) = let (name, var_def) = super::variable::get_doc_for_var_decl(var_decl);
super::variable::get_doc_for_var_decl(doc_parser, var_decl);
DocNode { DocNode {
kind: DocNodeKind::Variable, kind: DocNodeKind::Variable,
name, name,

View file

@ -14,10 +14,20 @@ pub enum DocNodeKind {
Namespace, Namespace,
} }
#[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub enum ParamKind {
Identifier,
Rest,
Array,
Object,
}
#[derive(Debug, Serialize, Clone)] #[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct ParamDef { pub struct ParamDef {
pub name: String, pub name: String,
pub kind: ParamKind,
pub ts_type: Option<super::ts_type::TsTypeDef>, pub ts_type: Option<super::ts_type::TsTypeDef>,
} }

83
cli/doc/params.rs Normal file
View file

@ -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),
}
}

View file

@ -347,7 +347,7 @@ impl DocParser {
return None; return None;
} }
let (name, function_def) = 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); let (js_doc, location) = self.details_for_span(fn_decl.function.span);
Some(DocNode { Some(DocNode {
kind: DocNodeKind::Function, kind: DocNodeKind::Function,
@ -367,8 +367,7 @@ impl DocParser {
if !var_decl.declare { if !var_decl.declare {
return None; return None;
} }
let (name, var_def) = let (name, var_def) = super::variable::get_doc_for_var_decl(var_decl);
super::variable::get_doc_for_var_decl(self, var_decl);
let (js_doc, location) = self.details_for_span(var_decl.span); let (js_doc, location) = self.details_for_span(var_decl.span);
Some(DocNode { Some(DocNode {
kind: DocNodeKind::Variable, kind: DocNodeKind::Variable,

View file

@ -52,7 +52,7 @@ async fn export_fn() {
* *
* Or not that many? * 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"); console.log("Hello world");
} }
"#; "#;
@ -65,9 +65,11 @@ export function foo(a: string, b: number): void {
"functionDef": { "functionDef": {
"isAsync": false, "isAsync": false,
"isGenerator": false, "isGenerator": false,
"typeParams": [],
"params": [ "params": [
{ {
"name": "a", "name": "a",
"kind": "identifier",
"tsType": { "tsType": {
"keyword": "string", "keyword": "string",
"kind": "keyword", "kind": "keyword",
@ -76,12 +78,56 @@ export function foo(a: string, b: number): void {
}, },
{ {
"name": "b", "name": "b",
"kind": "identifier",
"tsType": { "tsType": {
"keyword": "number", "keyword": "number",
"kind": "keyword", "kind": "keyword",
"repr": "number", "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": { "returnType": {
"keyword": "void", "keyword": "void",
@ -98,6 +144,7 @@ export function foo(a: string, b: number): void {
}, },
"name": "foo", "name": "foo",
}); });
let actual = serde_json::to_value(entry).unwrap(); let actual = serde_json::to_value(entry).unwrap();
assert_eq!(actual, expected_json); assert_eq!(actual, expected_json);
@ -107,6 +154,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] #[tokio::test]
async fn export_const() { async fn export_const() {
let source_code = let source_code =
@ -180,6 +306,7 @@ export class Foobar extends Fizz implements Buzz, Aldrin {
"isAbstract": false, "isAbstract": false,
"superClass": "Fizz", "superClass": "Fizz",
"implements": ["Buzz", "Aldrin"], "implements": ["Buzz", "Aldrin"],
"typeParams": [],
"constructors": [ "constructors": [
{ {
"jsDoc": "Constructor js doc", "jsDoc": "Constructor js doc",
@ -188,6 +315,7 @@ export class Foobar extends Fizz implements Buzz, Aldrin {
"params": [ "params": [
{ {
"name": "name", "name": "name",
"kind": "identifier",
"tsType": { "tsType": {
"repr": "string", "repr": "string",
"kind": "keyword", "kind": "keyword",
@ -195,12 +323,22 @@ export class Foobar extends Fizz implements Buzz, Aldrin {
} }
}, },
{ {
"name": "<TODO>", "name": "private2",
"tsType": null "kind": "identifier",
"tsType": {
"repr": "number",
"kind": "keyword",
"keyword": "number"
}
}, },
{ {
"name": "<TODO>", "name": "protected2",
"tsType": null "kind": "identifier",
"tsType": {
"repr": "number",
"kind": "keyword",
"keyword": "number"
}
} }
], ],
"location": { "location": {
@ -308,6 +446,7 @@ export class Foobar extends Fizz implements Buzz, Aldrin {
"typeName": "Promise" "typeName": "Promise"
} }
}, },
"typeParams": [],
"isAsync": true, "isAsync": true,
"isGenerator": false "isGenerator": false
}, },
@ -326,20 +465,21 @@ export class Foobar extends Fizz implements Buzz, Aldrin {
"kind": "method", "kind": "method",
"functionDef": { "functionDef": {
"params": [], "params": [],
"returnType": { "returnType": {
"repr": "void", "repr": "void",
"kind": "keyword", "kind": "keyword",
"keyword": "void" "keyword": "void"
},
"isAsync": false,
"isGenerator": false
}, },
"location": { "isAsync": false,
"filename": "test.ts", "isGenerator": false,
"line": 18, "typeParams": []
"col": 4 },
} "location": {
"filename": "test.ts",
"line": 18,
"col": 4
} }
}
] ]
} }
}); });
@ -391,6 +531,7 @@ export interface Reader {
"params": [ "params": [
{ {
"name": "buf", "name": "buf",
"kind": "identifier",
"tsType": { "tsType": {
"repr": "Uint8Array", "repr": "Uint8Array",
"kind": "typeRef", "kind": "typeRef",
@ -402,6 +543,7 @@ export interface Reader {
}, },
{ {
"name": "something", "name": "something",
"kind": "identifier",
"tsType": { "tsType": {
"repr": "unknown", "repr": "unknown",
"kind": "keyword", "kind": "keyword",
@ -409,6 +551,7 @@ export interface Reader {
} }
} }
], ],
"typeParams": [],
"returnType": { "returnType": {
"repr": "Promise", "repr": "Promise",
"kind": "typeRef", "kind": "typeRef",
@ -426,7 +569,8 @@ export interface Reader {
} }
], ],
"properties": [], "properties": [],
"callSignatures": [] "callSignatures": [],
"typeParams": [],
} }
}); });
let actual = serde_json::to_value(entry).unwrap(); let actual = serde_json::to_value(entry).unwrap();
@ -438,6 +582,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] #[tokio::test]
async fn export_type_alias() { async fn export_type_alias() {
let source_code = r#" let source_code = r#"
@ -459,6 +662,7 @@ export type NumberArray = Array<number>;
}, },
"jsDoc": "Array holding numbers", "jsDoc": "Array holding numbers",
"typeAliasDef": { "typeAliasDef": {
"typeParams": [],
"tsType": { "tsType": {
"repr": "Array", "repr": "Array",
"kind": "typeRef", "kind": "typeRef",
@ -751,6 +955,7 @@ async fn optional_return_type() {
"params": [ "params": [
{ {
"name": "a", "name": "a",
"kind": "identifier",
"tsType": { "tsType": {
"keyword": "number", "keyword": "number",
"kind": "keyword", "kind": "keyword",
@ -758,6 +963,7 @@ async fn optional_return_type() {
}, },
} }
], ],
"typeParams": [],
"returnType": null, "returnType": null,
"isAsync": false, "isAsync": false,
"isGenerator": false "isGenerator": false
@ -841,6 +1047,7 @@ export function fooFn(a: number) {
"params": [ "params": [
{ {
"name": "a", "name": "a",
"kind": "identifier",
"tsType": { "tsType": {
"keyword": "number", "keyword": "number",
"kind": "keyword", "kind": "keyword",
@ -848,6 +1055,7 @@ export function fooFn(a: number) {
}, },
} }
], ],
"typeParams": [],
"returnType": null, "returnType": null,
"isAsync": false, "isAsync": false,
"isGenerator": false "isGenerator": false

View file

@ -1,6 +1,8 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. // 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 super::ParamDef;
use crate::swc_common::SourceMap;
use crate::swc_ecma_ast; use crate::swc_ecma_ast;
use crate::swc_ecma_ast::TsArrayType; use crate::swc_ecma_ast::TsArrayType;
use crate::swc_ecma_ast::TsConditionalType; use crate::swc_ecma_ast::TsConditionalType;
@ -36,12 +38,12 @@ use serde::Serialize;
// * TsRestType(TsRestType), // * TsRestType(TsRestType),
// * TsUnionOrIntersectionType(TsUnionOrIntersectionType), // * TsUnionOrIntersectionType(TsUnionOrIntersectionType),
// * TsConditionalType(TsConditionalType), // * TsConditionalType(TsConditionalType),
// TsInferType(TsInferType),
// * TsParenthesizedType(TsParenthesizedType), // * TsParenthesizedType(TsParenthesizedType),
// * TsTypeOperator(TsTypeOperator), // * TsTypeOperator(TsTypeOperator),
// * TsIndexedAccessType(TsIndexedAccessType), // * TsIndexedAccessType(TsIndexedAccessType),
// TsMappedType(TsMappedType),
// * TsLitType(TsLitType), // * TsLitType(TsLitType),
// TsInferType(TsInferType),
// TsMappedType(TsMappedType),
// TsTypePredicate(TsTypePredicate), // TsTypePredicate(TsTypePredicate),
// TsImportType(TsImportType), // TsImportType(TsImportType),
// } // }
@ -340,24 +342,7 @@ impl Into<TsTypeDef> for &TsTypeLit {
let mut params = vec![]; let mut params = vec![];
for param in &ts_method_sig.params { for param in &ts_method_sig.params {
use crate::swc_ecma_ast::TsFnParam::*; let param_def = ts_fn_param_to_param_def(param);
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,
},
};
params.push(param_def); params.push(param_def);
} }
@ -366,10 +351,14 @@ impl Into<TsTypeDef> for &TsTypeLit {
.as_ref() .as_ref()
.map(|rt| (&*rt.type_ann).into()); .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 { let method_def = LiteralMethodDef {
name: "<TODO>".to_string(), name: "<TODO>".to_string(),
params, params,
return_type: maybe_return_type, return_type: maybe_return_type,
type_params,
}; };
methods.push(method_def); methods.push(method_def);
} }
@ -382,24 +371,7 @@ impl Into<TsTypeDef> for &TsTypeLit {
let mut params = vec![]; let mut params = vec![];
for param in &ts_prop_sig.params { for param in &ts_prop_sig.params {
use crate::swc_ecma_ast::TsFnParam::*; let param_def = ts_fn_param_to_param_def(param);
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,
},
};
params.push(param_def); params.push(param_def);
} }
@ -408,36 +380,23 @@ impl Into<TsTypeDef> for &TsTypeLit {
.as_ref() .as_ref()
.map(|rt| (&*rt.type_ann).into()); .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 { let prop_def = LiteralPropertyDef {
name, name,
params, params,
ts_type, ts_type,
computed: ts_prop_sig.computed, computed: ts_prop_sig.computed,
optional: ts_prop_sig.optional, optional: ts_prop_sig.optional,
type_params,
}; };
properties.push(prop_def); properties.push(prop_def);
} }
TsCallSignatureDecl(ts_call_sig) => { TsCallSignatureDecl(ts_call_sig) => {
let mut params = vec![]; let mut params = vec![];
for param in &ts_call_sig.params { for param in &ts_call_sig.params {
use crate::swc_ecma_ast::TsFnParam::*; let param_def = ts_fn_param_to_param_def(param);
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,
},
};
params.push(param_def); params.push(param_def);
} }
@ -446,7 +405,15 @@ impl Into<TsTypeDef> for &TsTypeLit {
.as_ref() .as_ref()
.map(|rt| (&*rt.type_ann).into()); .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); call_signatures.push(call_sig_def);
} }
// TODO: // TODO:
@ -495,68 +462,37 @@ impl Into<TsTypeDef> for &TsFnOrConstructorType {
let mut params = vec![]; let mut params = vec![];
for param in &ts_fn_type.params { for param in &ts_fn_type.params {
use crate::swc_ecma_ast::TsFnParam::*; let param_def = ts_fn_param_to_param_def(param);
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,
},
};
params.push(param_def); params.push(param_def);
} }
let type_params = maybe_type_param_decl_to_type_param_defs(
ts_fn_type.type_params.as_ref(),
);
TsFnOrConstructorDef { TsFnOrConstructorDef {
constructor: false, 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, params,
type_params,
} }
} }
TsConstructorType(ctor_type) => { TsConstructorType(ctor_type) => {
let mut params = vec![]; let mut params = vec![];
for param in &ctor_type.params { for param in &ctor_type.params {
use crate::swc_ecma_ast::TsFnParam::*; let param_def = ts_fn_param_to_param_def(param);
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,
},
};
params.push(param_def); params.push(param_def);
} }
let type_params = maybe_type_param_decl_to_type_param_defs(
ctor_type.type_params.as_ref(),
);
TsFnOrConstructorDef { TsFnOrConstructorDef {
constructor: true, constructor: true,
ts_type: (&*ctor_type.type_ann.type_ann).into(), ts_type: ts_type_ann_to_def(&ctor_type.type_ann),
params: vec![], params,
type_params,
} }
} }
}; };
@ -638,10 +574,10 @@ pub struct TsTypeOperatorDef {
#[derive(Debug, Serialize, Clone)] #[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct TsFnOrConstructorDef { pub struct TsFnOrConstructorDef {
// TODO: type_params
pub constructor: bool, pub constructor: bool,
pub ts_type: TsTypeDef, pub ts_type: TsTypeDef,
pub params: Vec<ParamDef>, pub params: Vec<ParamDef>,
pub type_params: Vec<TsTypeParamDef>,
} }
#[derive(Debug, Serialize, Clone)] #[derive(Debug, Serialize, Clone)]
@ -664,35 +600,29 @@ pub struct TsIndexedAccessDef {
#[derive(Debug, Serialize, Clone)] #[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct LiteralMethodDef { pub struct LiteralMethodDef {
// TODO: type_params
pub name: String, pub name: String,
// pub location: Location,
// pub js_doc: Option<String>,
pub params: Vec<ParamDef>, pub params: Vec<ParamDef>,
pub return_type: Option<TsTypeDef>, pub return_type: Option<TsTypeDef>,
pub type_params: Vec<TsTypeParamDef>,
} }
#[derive(Debug, Serialize, Clone)] #[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct LiteralPropertyDef { pub struct LiteralPropertyDef {
// TODO: type_params
pub name: String, pub name: String,
// pub location: Location,
// pub js_doc: Option<String>,
pub params: Vec<ParamDef>, pub params: Vec<ParamDef>,
pub computed: bool, pub computed: bool,
pub optional: bool, pub optional: bool,
pub ts_type: Option<TsTypeDef>, pub ts_type: Option<TsTypeDef>,
pub type_params: Vec<TsTypeParamDef>,
} }
#[derive(Debug, Serialize, Clone)] #[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct LiteralCallSignatureDef { pub struct LiteralCallSignatureDef {
// TODO: type_params
// pub location: Location,
// pub js_doc: Option<String>,
pub params: Vec<ParamDef>, pub params: Vec<ParamDef>,
pub ts_type: Option<TsTypeDef>, pub ts_type: Option<TsTypeDef>,
pub type_params: Vec<TsTypeParamDef>,
} }
#[derive(Debug, Serialize, Clone)] #[derive(Debug, Serialize, Clone)]
@ -732,7 +662,6 @@ pub struct TsTypeDef {
pub kind: Option<TsTypeDefKind>, pub kind: Option<TsTypeDefKind>,
// TODO: make this struct more conrete
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub keyword: Option<String>, pub keyword: Option<String>,
@ -785,10 +714,7 @@ pub struct TsTypeDef {
pub type_literal: Option<TsTypeLiteralDef>, pub type_literal: Option<TsTypeLiteralDef>,
} }
pub fn ts_type_ann_to_def( pub fn ts_type_ann_to_def(type_ann: &TsTypeAnn) -> TsTypeDef {
source_map: &SourceMap,
type_ann: &TsTypeAnn,
) -> TsTypeDef {
use crate::swc_ecma_ast::TsType::*; use crate::swc_ecma_ast::TsType::*;
match &*type_ann.type_ann { match &*type_ann.type_ann {
@ -808,16 +734,9 @@ pub fn ts_type_ann_to_def(
TsConditionalType(conditional_type) => conditional_type.into(), TsConditionalType(conditional_type) => conditional_type.into(),
TsIndexedAccessType(indexed_access_type) => indexed_access_type.into(), TsIndexedAccessType(indexed_access_type) => indexed_access_type.into(),
TsTypeLit(type_literal) => type_literal.into(), TsTypeLit(type_literal) => type_literal.into(),
_ => { _ => TsTypeDef {
let repr = source_map repr: "<TODO>".to_string(),
.span_to_snippet(type_ann.span) ..Default::default()
.expect("Class prop type not found"); },
let repr = repr.trim_start_matches(':').trim_start().to_string();
TsTypeDef {
repr,
..Default::default()
}
}
} }
} }

57
cli/doc/ts_type_param.rs Normal file
View file

@ -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![]
}
}

View file

@ -1,15 +1,16 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. // 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::parser::DocParser;
use super::ts_type::TsTypeDef; 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)] #[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct TypeAliasDef { pub struct TypeAliasDef {
pub ts_type: TsTypeDef, pub ts_type: TsTypeDef,
// TODO: type_params pub type_params: Vec<TsTypeParamDef>,
} }
pub fn get_doc_for_ts_type_alias_decl( pub fn get_doc_for_ts_type_alias_decl(
@ -18,8 +19,13 @@ pub fn get_doc_for_ts_type_alias_decl(
) -> (String, TypeAliasDef) { ) -> (String, TypeAliasDef) {
let alias_name = type_alias_decl.id.sym.to_string(); let alias_name = type_alias_decl.id.sym.to_string();
let ts_type = type_alias_decl.type_ann.as_ref().into(); let ts_type = type_alias_decl.type_ann.as_ref().into();
let type_params = maybe_type_param_decl_to_type_param_defs(
let type_alias_def = TypeAliasDef { ts_type }; type_alias_decl.type_params.as_ref(),
);
let type_alias_def = TypeAliasDef {
ts_type,
type_params,
};
(alias_name, type_alias_def) (alias_name, type_alias_def)
} }

View file

@ -2,7 +2,6 @@
use crate::swc_ecma_ast; use crate::swc_ecma_ast;
use serde::Serialize; use serde::Serialize;
use super::parser::DocParser;
use super::ts_type::ts_type_ann_to_def; use super::ts_type::ts_type_ann_to_def;
use super::ts_type::TsTypeDef; use super::ts_type::TsTypeDef;
@ -13,12 +12,12 @@ pub struct VariableDef {
pub kind: swc_ecma_ast::VarDeclKind, 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( pub fn get_doc_for_var_decl(
doc_parser: &DocParser,
var_decl: &swc_ecma_ast::VarDecl, var_decl: &swc_ecma_ast::VarDecl,
) -> (String, VariableDef) { ) -> (String, VariableDef) {
assert!(!var_decl.decls.is_empty()); assert!(!var_decl.decls.is_empty());
// TODO: support multiple declarators
let var_declarator = var_decl.decls.get(0).unwrap(); let var_declarator = var_decl.decls.get(0).unwrap();
let var_name = match &var_declarator.name { 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 { let maybe_ts_type = match &var_declarator.name {
swc_ecma_ast::Pat::Ident(ident) => ident swc_ecma_ast::Pat::Ident(ident) => {
.type_ann ident.type_ann.as_ref().map(|rt| ts_type_ann_to_def(rt))
.as_ref() }
.map(|rt| ts_type_ann_to_def(&doc_parser.source_map, rt)),
_ => None, _ => None,
}; };