1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-26 16:09:27 -05:00

fix(doc): Safely deal with optional type (#4526)

This commit is contained in:
Luca Casonato 2020-03-30 04:41:27 +02:00 committed by GitHub
parent 92f1c71a6f
commit d795d34362
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 94 additions and 30 deletions

View file

@ -90,12 +90,8 @@ fn format_(doc_nodes: Vec<doc::DocNode>, indent: i64) -> String {
for node in sorted {
output.push_str(&format_signature(&node, indent));
if node.js_doc.is_some() {
output.push_str(&format_jsdoc(
node.js_doc.as_ref().unwrap().to_string(),
true,
indent,
));
if let Some(js_doc) = node.js_doc {
output.push_str(&format_jsdoc(js_doc, true, indent));
}
output.push_str("\n");
if DocNodeKind::Namespace == node.kind {
@ -115,9 +111,9 @@ fn render_params(params: Vec<doc::ParamDef>) -> String {
if !params.is_empty() {
for param in params {
rendered += param.name.as_str();
if param.ts_type.is_some() {
if let Some(ts_type) = param.ts_type {
rendered += ": ";
rendered += render_ts_type(param.ts_type.unwrap()).as_str();
rendered += render_ts_type(ts_type).as_str();
}
rendered += ", ";
}
@ -215,25 +211,40 @@ fn render_ts_type(ts_type: doc::ts_type::TsTypeDef) -> String {
let type_literal = ts_type.type_literal.unwrap();
for node in type_literal.call_signatures {
output += format!(
"({}): {}, ",
"({}){}, ",
render_params(node.params),
render_ts_type(node.ts_type.unwrap())
if let Some(ts_type) = node.ts_type {
format!(": {}", render_ts_type(ts_type))
} else {
"".to_string()
}
)
.as_str()
}
for node in type_literal.methods {
output += format!(
"{}({}): {}, ",
"{}({}){}, ",
node.name,
render_params(node.params),
render_ts_type(node.return_type.unwrap())
if let Some(return_type) = node.return_type {
format!(": {}", render_ts_type(return_type))
} else {
"".to_string()
}
)
.as_str()
}
for node in type_literal.properties {
output +=
format!("{}: {}, ", node.name, render_ts_type(node.ts_type.unwrap()))
.as_str()
output += format!(
"{}{}, ",
node.name,
if let Some(ts_type) = node.ts_type {
format!(": {}", render_ts_type(ts_type))
} else {
"".to_string()
}
)
.as_str()
}
if !output.is_empty() {
output.truncate(output.len() - 2);
@ -250,9 +261,8 @@ fn render_ts_type(ts_type: doc::ts_type::TsTypeDef) -> String {
TsTypeDefKind::TypeRef => {
let type_ref = ts_type.type_ref.unwrap();
let mut final_output = type_ref.type_name;
if type_ref.type_params.is_some() {
if let Some(type_params) = type_ref.type_params {
let mut output = "".to_string();
let type_params = type_ref.type_params.unwrap();
if !type_params.is_empty() {
for ts_type in type_params {
output += render_ts_type(ts_type).as_str();
@ -328,7 +338,7 @@ fn format_class_details(node: doc::DocNode) -> String {
}) {
details.push_str(&add_indent(
format!(
"{}{}: {}\n",
"{}{}{}\n",
colors::magenta(
match node
.accessibility
@ -339,7 +349,11 @@ fn format_class_details(node: doc::DocNode) -> String {
}
),
colors::bold(node.name.clone()),
render_ts_type(node.ts_type.clone().unwrap())
if let Some(ts_type) = node.ts_type.clone() {
format!(": {}", render_ts_type(ts_type))
} else {
"".to_string()
}
),
1,
));
@ -353,7 +367,7 @@ fn format_class_details(node: doc::DocNode) -> String {
let function_def = node.function_def.clone();
details.push_str(&add_indent(
format!(
"{}{}{}({}): {}\n",
"{}{}{}({}){}\n",
colors::magenta(
match node
.accessibility
@ -370,7 +384,11 @@ fn format_class_details(node: doc::DocNode) -> String {
}),
colors::bold(node.name.clone()),
render_params(function_def.params),
render_ts_type(function_def.return_type.unwrap())
if let Some(return_type) = function_def.return_type {
format!(": {}", render_ts_type(return_type))
} else {
"".to_string()
}
),
1,
));
@ -392,17 +410,17 @@ fn format_namespace_details(node: doc::DocNode) -> String {
fn format_function_signature(node: &doc::DocNode, indent: i64) -> String {
let function_def = node.function_def.clone().unwrap();
let return_type = function_def.return_type.unwrap();
add_indent(
format!(
"{} {}{}\n",
"{} {}({}){}\n",
colors::magenta("function".to_string()),
colors::bold(node.name.clone()),
format!(
"({}): {}",
render_params(function_def.params),
render_ts_type(return_type).as_str()
)
render_params(function_def.params),
if let Some(return_type) = function_def.return_type {
format!(": {}", render_ts_type(return_type).as_str())
} else {
"".to_string()
}
),
indent,
)
@ -430,8 +448,8 @@ fn format_variable_signature(node: &doc::DocNode, indent: i64) -> String {
swc_ecma_ast::VarDeclKind::Var => "var".to_string(),
}),
colors::bold(node.name.clone()),
if variable_def.ts_type.is_some() {
format!(": {}", render_ts_type(variable_def.ts_type.unwrap()))
if let Some(ts_type) = variable_def.ts_type {
format!(": {}", render_ts_type(ts_type))
} else {
"".to_string()
}

View file

@ -590,3 +590,49 @@ export namespace RootNs {
.contains("namespace RootNs")
);
}
#[test]
fn optional_return_type() {
let source_code = r#"
export function foo(a: number) {
return a;
}
"#;
let entries = DocParser::default()
.parse("test.ts".to_string(), source_code.to_string())
.unwrap();
assert_eq!(entries.len(), 1);
let entry = &entries[0];
let expected_json = json!({
"kind": "function",
"name": "foo",
"location": {
"filename": "test.ts",
"line": 2,
"col": 2
},
"jsDoc": null,
"functionDef": {
"params": [
{
"name": "a",
"tsType": {
"keyword": "number",
"kind": "keyword",
"repr": "number",
},
}
],
"returnType": null,
"isAsync": false,
"isGenerator": false
}
});
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("function foo(a: number)")
);
}