From 2b2d800b43e548e615abef80278d20dda5ae7d42 Mon Sep 17 00:00:00 2001 From: uki00a Date: Tue, 9 Jun 2020 21:12:47 +0900 Subject: [PATCH] feat(doc): display all overloads in cli details view (#6186) --- cli/doc/mod.rs | 65 ++++++++++--------- cli/doc/tests.rs | 48 ++++++++++++++ cli/main.rs | 12 ++-- ..._displays_all_overloads_in_details_view.ts | 6 ++ ...plays_all_overloads_in_details_view.ts.out | 12 ++++ cli/tests/integration_tests.rs | 7 +- 6 files changed, 116 insertions(+), 34 deletions(-) create mode 100644 cli/tests/060_deno_doc_displays_all_overloads_in_details_view.ts create mode 100644 cli/tests/060_deno_doc_displays_all_overloads_in_details_view.ts.out diff --git a/cli/doc/mod.rs b/cli/doc/mod.rs index b0f7cf60a8..81cc2f9fb4 100644 --- a/cli/doc/mod.rs +++ b/cli/doc/mod.rs @@ -24,43 +24,50 @@ pub use parser::DocParser; #[cfg(test)] mod tests; -pub fn find_node_by_name_recursively( +pub fn find_nodes_by_name_recursively( doc_nodes: Vec, name: String, -) -> Option { +) -> Vec { let mut parts = name.splitn(2, '.'); let name = parts.next(); let leftover = parts.next(); - name?; - let node = find_node_by_name(doc_nodes, name.unwrap().to_string()); - match node { - Some(node) => match node.kind { - DocNodeKind::Namespace => { - if let Some(leftover) = leftover { - find_node_by_name_recursively( - node.namespace_def.unwrap().elements, - leftover.to_string(), - ) - } else { - Some(node) - } + if name.is_none() { + return doc_nodes; + } + + let name = name.unwrap(); + let doc_nodes = find_nodes_by_name(doc_nodes, name.to_string()); + + let mut found: Vec = vec![]; + match leftover { + Some(leftover) => { + for node in doc_nodes { + let children = find_children_by_name(node, leftover.to_string()); + found.extend(children); } - _ => { - if leftover.is_none() { - Some(node) - } else { - None - } - } - }, - _ => None, + found + } + None => doc_nodes, } } -fn find_node_by_name(doc_nodes: Vec, name: String) -> Option { - let node = doc_nodes.iter().find(|node| node.name == name); - match node { - Some(node) => Some(node.clone()), - None => None, +fn find_nodes_by_name(doc_nodes: Vec, name: String) -> Vec { + let mut found: Vec = vec![]; + for node in doc_nodes { + if node.name == name { + found.push(node); + } + } + found +} + +fn find_children_by_name(node: DocNode, name: String) -> Vec { + match node.kind { + DocNodeKind::Namespace => { + let namespace_def = node.namespace_def.unwrap(); + find_nodes_by_name_recursively(namespace_def.elements, name) + } + // TODO(#4516) handle class, interface etc... + _ => vec![], } } diff --git a/cli/doc/tests.rs b/cli/doc/tests.rs index f3355a520c..8886f76be7 100644 --- a/cli/doc/tests.rs +++ b/cli/doc/tests.rs @@ -1557,3 +1557,51 @@ export type numLit = 5; ]); assert_eq!(actual, expected_json); } + +#[tokio::test] +async fn filter_nodes_by_name() { + use super::find_nodes_by_name_recursively; + let source_code = r#" +export namespace Deno { + export class Buffer {} + export function test(options: object): void; + export function test(name: string, fn: Function): void; + export function test(name: string | object, fn?: Function): void {} +} + +export namespace Deno { + export namespace Inner { + export function a(): void {} + export const b = 100; + } +} +"#; + let loader = + TestLoader::new(vec![("test.ts".to_string(), source_code.to_string())]); + let entries = DocParser::new(loader).parse("test.ts").await.unwrap(); + + let found = + find_nodes_by_name_recursively(entries.clone(), "Deno".to_string()); + assert_eq!(found.len(), 2); + assert_eq!(found[0].name, "Deno".to_string()); + assert_eq!(found[1].name, "Deno".to_string()); + + let found = + find_nodes_by_name_recursively(entries.clone(), "Deno.test".to_string()); + assert_eq!(found.len(), 3); + assert_eq!(found[0].name, "test".to_string()); + assert_eq!(found[1].name, "test".to_string()); + assert_eq!(found[2].name, "test".to_string()); + + let found = + find_nodes_by_name_recursively(entries.clone(), "Deno.Inner.a".to_string()); + assert_eq!(found.len(), 1); + assert_eq!(found[0].name, "a".to_string()); + + let found = + find_nodes_by_name_recursively(entries.clone(), "Deno.test.a".to_string()); + assert_eq!(found.len(), 0); + + let found = find_nodes_by_name_recursively(entries, "a.b.c".to_string()); + assert_eq!(found.len(), 0); +} diff --git a/cli/main.rs b/cli/main.rs index 3c16df974f..909295439f 100644 --- a/cli/main.rs +++ b/cli/main.rs @@ -578,13 +578,17 @@ async fn doc_command( serde_json::to_writer_pretty(writer, &doc_nodes).map_err(ErrBox::from) } else { let details = if let Some(filter) = maybe_filter { - let node = doc::find_node_by_name_recursively(doc_nodes, filter.clone()); - if let Some(node) = node { - doc::printer::format_details(node) - } else { + let nodes = + doc::find_nodes_by_name_recursively(doc_nodes, filter.clone()); + if nodes.is_empty() { eprintln!("Node {} was not found!", filter); std::process::exit(1); } + let mut details = String::new(); + for node in nodes { + details.push_str(doc::printer::format_details(node).as_str()); + } + details } else { doc::printer::format(doc_nodes) }; diff --git a/cli/tests/060_deno_doc_displays_all_overloads_in_details_view.ts b/cli/tests/060_deno_doc_displays_all_overloads_in_details_view.ts new file mode 100644 index 0000000000..479dfca79d --- /dev/null +++ b/cli/tests/060_deno_doc_displays_all_overloads_in_details_view.ts @@ -0,0 +1,6 @@ +/* eslint-disable */ +export namespace NS { + export function test(name: string, fn: Function): void; + export function test(options: object): void; + export function test(name: string | object, fn?: Function): void {} +} diff --git a/cli/tests/060_deno_doc_displays_all_overloads_in_details_view.ts.out b/cli/tests/060_deno_doc_displays_all_overloads_in_details_view.ts.out new file mode 100644 index 0000000000..b7b4076f92 --- /dev/null +++ b/cli/tests/060_deno_doc_displays_all_overloads_in_details_view.ts.out @@ -0,0 +1,12 @@ +Defined in [WILDCARD]/cli/tests/060_deno_doc_displays_all_overloads_in_details_view.ts:3:2 + +function test(name: string, fn: Function): void + +Defined in [WILDCARD]/cli/tests/060_deno_doc_displays_all_overloads_in_details_view.ts:4:2 + +function test(options: object): void + +Defined in [WILDCARD]cli/tests/060_deno_doc_displays_all_overloads_in_details_view.ts:5:2 + +function test(name: string | object, fn?: Function): void + diff --git a/cli/tests/integration_tests.rs b/cli/tests/integration_tests.rs index 6583f5f254..2da5eebcb5 100644 --- a/cli/tests/integration_tests.rs +++ b/cli/tests/integration_tests.rs @@ -500,7 +500,7 @@ fn ts_dependency_recompilation() { function print(str: string): void { console.log(str); } - + print(foo);", ) .unwrap(); @@ -1419,6 +1419,11 @@ itest!(_059_fs_relative_path_perm { exit_code: 1, }); +itest!(_060_deno_doc_displays_all_overloads_in_details_view { + args: "doc 060_deno_doc_displays_all_overloads_in_details_view.ts NS.test", + output: "060_deno_doc_displays_all_overloads_in_details_view.ts.out", +}); + itest!(js_import_detect { args: "run --quiet --reload js_import_detect.ts", output: "js_import_detect.ts.out",