forked from denoland/deno
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add "deno doc" subcommand (denoland#4500)
- Loading branch information
1 parent
bced525
commit 3fac487
Showing
18 changed files
with
3,233 additions
and
4 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,207 @@ | ||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. | ||
use serde::Serialize; | ||
use swc_common; | ||
use swc_common::SourceMap; | ||
use swc_common::Spanned; | ||
use swc_ecma_ast; | ||
|
||
use super::function::function_to_function_def; | ||
use super::function::FunctionDef; | ||
use super::parser::DocParser; | ||
use super::ts_type::ts_type_ann_to_def; | ||
use super::ts_type::TsTypeDef; | ||
use super::Location; | ||
use super::ParamDef; | ||
|
||
#[derive(Debug, Serialize, Clone)] | ||
#[serde(rename_all = "camelCase")] | ||
pub struct ClassConstructorDef { | ||
pub js_doc: Option<String>, | ||
pub accessibility: Option<swc_ecma_ast::Accessibility>, | ||
pub name: String, | ||
pub params: Vec<ParamDef>, | ||
pub location: Location, | ||
} | ||
|
||
#[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_ecma_ast::Accessibility>, | ||
pub is_abstract: bool, | ||
pub is_static: bool, | ||
pub name: String, | ||
pub location: Location, | ||
} | ||
|
||
#[derive(Debug, Serialize, Clone)] | ||
#[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, | ||
pub name: String, | ||
pub kind: swc_ecma_ast::MethodKind, | ||
pub function_def: FunctionDef, | ||
pub location: Location, | ||
} | ||
|
||
#[derive(Debug, Serialize, Clone)] | ||
#[serde(rename_all = "camelCase")] | ||
pub struct ClassDef { | ||
// TODO: decorators, super_class, implements, | ||
// type_params, super_type_params | ||
pub is_abstract: bool, | ||
pub constructors: Vec<ClassConstructorDef>, | ||
pub properties: Vec<ClassPropertyDef>, | ||
pub methods: Vec<ClassMethodDef>, | ||
} | ||
|
||
fn prop_name_to_string( | ||
source_map: &SourceMap, | ||
prop_name: &swc_ecma_ast::PropName, | ||
) -> String { | ||
use swc_ecma_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.span_to_snippet(comp_prop_name.span).unwrap() | ||
} | ||
} | ||
} | ||
|
||
pub fn get_doc_for_class_decl( | ||
doc_parser: &DocParser, | ||
class_decl: &swc_ecma_ast::ClassDecl, | ||
) -> (String, ClassDef) { | ||
let mut constructors = vec![]; | ||
let mut methods = vec![]; | ||
let mut properties = vec![]; | ||
|
||
for member in &class_decl.class.body { | ||
use swc_ecma_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(&doc_parser.source_map, &ctor.key); | ||
|
||
let mut params = vec![]; | ||
|
||
for param in &ctor.params { | ||
use swc_ecma_ast::Pat; | ||
use 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, | ||
} | ||
} | ||
_ => ParamDef { | ||
name: "<TODO>".to_string(), | ||
ts_type: None, | ||
}, | ||
}, | ||
TsParamProp(_) => ParamDef { | ||
name: "<TODO>".to_string(), | ||
ts_type: None, | ||
}, | ||
}; | ||
params.push(param_def); | ||
} | ||
|
||
let constructor_def = ClassConstructorDef { | ||
js_doc: ctor_js_doc, | ||
accessibility: ctor.accessibility, | ||
name: constructor_name, | ||
params, | ||
location: doc_parser | ||
.source_map | ||
.lookup_char_pos(ctor.span.lo()) | ||
.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(&doc_parser.source_map, &class_method.key); | ||
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, | ||
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 | ||
.source_map | ||
.lookup_char_pos(class_method.span.lo()) | ||
.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(&doc_parser.source_map, rt)); | ||
|
||
use swc_ecma_ast::Expr; | ||
let prop_name = match &*class_prop.key { | ||
Expr::Ident(ident) => ident.sym.to_string(), | ||
_ => "<TODO>".to_string(), | ||
}; | ||
|
||
let prop_def = ClassPropertyDef { | ||
js_doc: prop_js_doc, | ||
ts_type, | ||
readonly: class_prop.readonly, | ||
is_abstract: class_prop.is_abstract, | ||
is_static: class_prop.is_static, | ||
accessibility: class_prop.accessibility, | ||
name: prop_name, | ||
location: doc_parser | ||
.source_map | ||
.lookup_char_pos(class_prop.span.lo()) | ||
.into(), | ||
}; | ||
properties.push(prop_def); | ||
} | ||
// TODO: | ||
TsIndexSignature(_) => {} | ||
PrivateMethod(_) => {} | ||
PrivateProp(_) => {} | ||
} | ||
} | ||
|
||
let class_name = class_decl.ident.sym.to_string(); | ||
let class_def = ClassDef { | ||
is_abstract: class_decl.class.is_abstract, | ||
constructors, | ||
properties, | ||
methods, | ||
}; | ||
|
||
(class_name, class_def) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. | ||
use serde::Serialize; | ||
use swc_ecma_ast; | ||
|
||
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_ecma_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_ecma_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) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. | ||
use serde::Serialize; | ||
use swc_ecma_ast; | ||
|
||
use super::parser::DocParser; | ||
use super::ts_type::ts_type_ann_to_def; | ||
use super::ts_type::TsTypeDef; | ||
use super::ParamDef; | ||
|
||
#[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, | ||
// TODO: type_params, 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 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, | ||
}, | ||
}; | ||
|
||
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)); | ||
|
||
FunctionDef { | ||
params, | ||
return_type: maybe_return_type, | ||
is_async: function.is_async, | ||
is_generator: function.is_generator, | ||
} | ||
} | ||
|
||
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); | ||
(name, fn_def) | ||
} |
Oops, something went wrong.