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:
parent
92f1c71a6f
commit
d795d34362
2 changed files with 94 additions and 30 deletions
|
@ -90,12 +90,8 @@ fn format_(doc_nodes: Vec<doc::DocNode>, indent: i64) -> String {
|
||||||
|
|
||||||
for node in sorted {
|
for node in sorted {
|
||||||
output.push_str(&format_signature(&node, indent));
|
output.push_str(&format_signature(&node, indent));
|
||||||
if node.js_doc.is_some() {
|
if let Some(js_doc) = node.js_doc {
|
||||||
output.push_str(&format_jsdoc(
|
output.push_str(&format_jsdoc(js_doc, true, indent));
|
||||||
node.js_doc.as_ref().unwrap().to_string(),
|
|
||||||
true,
|
|
||||||
indent,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
output.push_str("\n");
|
output.push_str("\n");
|
||||||
if DocNodeKind::Namespace == node.kind {
|
if DocNodeKind::Namespace == node.kind {
|
||||||
|
@ -115,9 +111,9 @@ fn render_params(params: Vec<doc::ParamDef>) -> String {
|
||||||
if !params.is_empty() {
|
if !params.is_empty() {
|
||||||
for param in params {
|
for param in params {
|
||||||
rendered += param.name.as_str();
|
rendered += param.name.as_str();
|
||||||
if param.ts_type.is_some() {
|
if let Some(ts_type) = param.ts_type {
|
||||||
rendered += ": ";
|
rendered += ": ";
|
||||||
rendered += render_ts_type(param.ts_type.unwrap()).as_str();
|
rendered += render_ts_type(ts_type).as_str();
|
||||||
}
|
}
|
||||||
rendered += ", ";
|
rendered += ", ";
|
||||||
}
|
}
|
||||||
|
@ -215,25 +211,40 @@ fn render_ts_type(ts_type: doc::ts_type::TsTypeDef) -> String {
|
||||||
let type_literal = ts_type.type_literal.unwrap();
|
let type_literal = ts_type.type_literal.unwrap();
|
||||||
for node in type_literal.call_signatures {
|
for node in type_literal.call_signatures {
|
||||||
output += format!(
|
output += format!(
|
||||||
"({}): {}, ",
|
"({}){}, ",
|
||||||
render_params(node.params),
|
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()
|
.as_str()
|
||||||
}
|
}
|
||||||
for node in type_literal.methods {
|
for node in type_literal.methods {
|
||||||
output += format!(
|
output += format!(
|
||||||
"{}({}): {}, ",
|
"{}({}){}, ",
|
||||||
node.name,
|
node.name,
|
||||||
render_params(node.params),
|
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()
|
.as_str()
|
||||||
}
|
}
|
||||||
for node in type_literal.properties {
|
for node in type_literal.properties {
|
||||||
output +=
|
output += format!(
|
||||||
format!("{}: {}, ", node.name, render_ts_type(node.ts_type.unwrap()))
|
"{}{}, ",
|
||||||
.as_str()
|
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() {
|
if !output.is_empty() {
|
||||||
output.truncate(output.len() - 2);
|
output.truncate(output.len() - 2);
|
||||||
|
@ -250,9 +261,8 @@ fn render_ts_type(ts_type: doc::ts_type::TsTypeDef) -> String {
|
||||||
TsTypeDefKind::TypeRef => {
|
TsTypeDefKind::TypeRef => {
|
||||||
let type_ref = ts_type.type_ref.unwrap();
|
let type_ref = ts_type.type_ref.unwrap();
|
||||||
let mut final_output = type_ref.type_name;
|
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 mut output = "".to_string();
|
||||||
let type_params = type_ref.type_params.unwrap();
|
|
||||||
if !type_params.is_empty() {
|
if !type_params.is_empty() {
|
||||||
for ts_type in type_params {
|
for ts_type in type_params {
|
||||||
output += render_ts_type(ts_type).as_str();
|
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(
|
details.push_str(&add_indent(
|
||||||
format!(
|
format!(
|
||||||
"{}{}: {}\n",
|
"{}{}{}\n",
|
||||||
colors::magenta(
|
colors::magenta(
|
||||||
match node
|
match node
|
||||||
.accessibility
|
.accessibility
|
||||||
|
@ -339,7 +349,11 @@ fn format_class_details(node: doc::DocNode) -> String {
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
colors::bold(node.name.clone()),
|
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,
|
1,
|
||||||
));
|
));
|
||||||
|
@ -353,7 +367,7 @@ fn format_class_details(node: doc::DocNode) -> String {
|
||||||
let function_def = node.function_def.clone();
|
let function_def = node.function_def.clone();
|
||||||
details.push_str(&add_indent(
|
details.push_str(&add_indent(
|
||||||
format!(
|
format!(
|
||||||
"{}{}{}({}): {}\n",
|
"{}{}{}({}){}\n",
|
||||||
colors::magenta(
|
colors::magenta(
|
||||||
match node
|
match node
|
||||||
.accessibility
|
.accessibility
|
||||||
|
@ -370,7 +384,11 @@ fn format_class_details(node: doc::DocNode) -> String {
|
||||||
}),
|
}),
|
||||||
colors::bold(node.name.clone()),
|
colors::bold(node.name.clone()),
|
||||||
render_params(function_def.params),
|
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,
|
1,
|
||||||
));
|
));
|
||||||
|
@ -392,17 +410,17 @@ fn format_namespace_details(node: doc::DocNode) -> String {
|
||||||
|
|
||||||
fn format_function_signature(node: &doc::DocNode, indent: i64) -> String {
|
fn format_function_signature(node: &doc::DocNode, indent: i64) -> String {
|
||||||
let function_def = node.function_def.clone().unwrap();
|
let function_def = node.function_def.clone().unwrap();
|
||||||
let return_type = function_def.return_type.unwrap();
|
|
||||||
add_indent(
|
add_indent(
|
||||||
format!(
|
format!(
|
||||||
"{} {}{}\n",
|
"{} {}({}){}\n",
|
||||||
colors::magenta("function".to_string()),
|
colors::magenta("function".to_string()),
|
||||||
colors::bold(node.name.clone()),
|
colors::bold(node.name.clone()),
|
||||||
format!(
|
render_params(function_def.params),
|
||||||
"({}): {}",
|
if let Some(return_type) = function_def.return_type {
|
||||||
render_params(function_def.params),
|
format!(": {}", render_ts_type(return_type).as_str())
|
||||||
render_ts_type(return_type).as_str()
|
} else {
|
||||||
)
|
"".to_string()
|
||||||
|
}
|
||||||
),
|
),
|
||||||
indent,
|
indent,
|
||||||
)
|
)
|
||||||
|
@ -430,8 +448,8 @@ fn format_variable_signature(node: &doc::DocNode, indent: i64) -> String {
|
||||||
swc_ecma_ast::VarDeclKind::Var => "var".to_string(),
|
swc_ecma_ast::VarDeclKind::Var => "var".to_string(),
|
||||||
}),
|
}),
|
||||||
colors::bold(node.name.clone()),
|
colors::bold(node.name.clone()),
|
||||||
if variable_def.ts_type.is_some() {
|
if let Some(ts_type) = variable_def.ts_type {
|
||||||
format!(": {}", render_ts_type(variable_def.ts_type.unwrap()))
|
format!(": {}", render_ts_type(ts_type))
|
||||||
} else {
|
} else {
|
||||||
"".to_string()
|
"".to_string()
|
||||||
}
|
}
|
||||||
|
|
|
@ -590,3 +590,49 @@ export namespace RootNs {
|
||||||
.contains("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)")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue