Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions src/html/symbols/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,13 +297,17 @@ fn render_single_function(
.enumerate()
.map(|(i, param)| {
let (name, str_name) = crate::html::parameters::param_name(param, i);
// `@param` tag names are bare identifiers, but the rendered name of a
// rest parameter carries a `...` prefix (e.g. `...rest`). Strip it so the
// doc lookup matches the tag (see issue #574).
let lookup_name = str_name.trim_start_matches('.');
let id = IdBuilder::new_with_parent(ctx, &overload_id)
.kind(IdKind::Parameter)
.name(&str_name)
.build();

let (mut default, optional) = if let Some((_doc, optional, default)) =
param_docs.get(name.as_str())
param_docs.get(lookup_name)
{
((**default).to_owned(), *optional)
} else {
Expand Down Expand Up @@ -342,7 +346,7 @@ fn render_single_function(
};

let param_doc = param_docs
.get(name.as_str())
.get(lookup_name)
.and_then(|(doc, _, _)| doc.as_deref());

let (diff_status, old_content) =
Expand Down
58 changes: 58 additions & 0 deletions tests/html_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,64 @@ export class Foo {
);
}

// Regression test for https://github.com/denoland/deno_doc/issues/574:
// `@param` documentation must render for rest/spread parameters. The rendered
// parameter name carries a `...` prefix, but the JSDoc `@param` tag name does
// not, so the doc lookup has to match on the bare identifier.
#[tokio::test]
async fn html_rest_param_jsdoc() {
let source = r#"
/**
* Sums numbers.
*
* @param first the leading number
* @param rest the trailing numbers
*/
export function sum(first: number, ...rest: number[]): number {
return first + rest.reduce((a, b) => a + b, 0);
}
"#;

let ctx = GenerateCtx::create_basic(
GenerateOptions {
package_name: None,
main_entrypoint: None,
href_resolver: Arc::new(EmptyResolver),
usage_composer: Some(Arc::new(EmptyResolver)),
rewrite_map: None,
category_docs: None,
disable_search: false,
symbol_redirect_map: None,
default_symbol_map: None,
markdown_renderer: comrak::create_renderer(None, None, None),
markdown_stripper: Arc::new(comrak::strip),
head_inject: None,
id_prefix: None,
diff_only: false,
},
parse_source(source).await,
None,
)
.unwrap();

let files = generate(ctx).unwrap();

let sum_page = files
.get("./~/sum.html")
.expect("function symbol page should be generated");

// The non-rest parameter has always rendered its doc.
assert!(
sum_page.contains("the leading number"),
"expected the first parameter's @param doc to render"
);
// The rest parameter's @param doc must render too (the bug in #574).
assert!(
sum_page.contains("the trailing numbers"),
"expected the rest parameter's @param doc to render"
);
}

#[tokio::test]
async fn diff_kind_change() {
let test_dir = std::env::current_dir()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ expression: pages
],
[
"./~/createPipeline.json",
"{\"kind\":\"SymbolPageCtx\",\"html_head_ctx\":{\"title\":\"createPipeline - default - documentation\",\"current_file\":\".\",\"stylesheet_url\":\"../styles.css\",\"page_stylesheet_url\":\"../page.css\",\"reset_stylesheet_url\":\"../reset.css\",\"url_search_index\":\"../search_index.js\",\"script_js\":\"../script.js\",\"fuse_js\":\"../fuse.js\",\"search_js\":\"../search.js\",\"darkmode_toggle_js\":\"../darkmode_toggle.js\",\"head_inject\":null,\"disable_search\":false},\"symbol_group_ctx\":{\"name\":\"createPipeline\",\"symbols\":[{\"kind\":{\"kind\":\"Function\",\"char\":\"f\",\"title\":\"Function\",\"title_lowercase\":\"function\",\"title_plural\":\"Functions\"},\"usage\":null,\"tags\":[],\"subtitle\":null,\"content\":[{\"kind\":\"function\",\"value\":{\"functions\":[{\"anchor\":{\"id\":\"function_createpipeline_0\"},\"name\":\"createPipeline\",\"summary\":\"(<span><span><span>...middlewares</span><span>: <a href=\\\"../././~/Middleware.html\\\" class=\\\"link td-ref\\\">Middleware</a>[]</span></span></span>)<span>: <a href=\\\"../././~/Middleware.html\\\" class=\\\"link td-ref\\\">Middleware</a></span>\",\"deprecated\":null,\"content\":{\"id\":\"\",\"docs\":\"<div class=\\\"markdown\\\"><p>Create middleware pipeline.</p>\\n</div>\",\"sections\":[{\"header\":{\"title\":\"Parameters\",\"anchor\":{\"id\":\"parameters\"},\"href\":null,\"doc\":null},\"content\":{\"kind\":\"doc_entry\",\"content\":[{\"name_prefix\":null,\"name\":\"<span>...middlewares</span>\",\"name_href\":null,\"content\":\"<span>: <a href=\\\"../././~/Middleware.html\\\" class=\\\"link td-ref\\\">Middleware</a>[]</span>\",\"anchor\":{\"id\":\"function_createpipeline_0_parameter____middlewares\"},\"tags\":[],\"js_doc\":null,\"source_href\":null}]}},{\"header\":{\"title\":\"Return Type\",\"anchor\":{\"id\":\"return-type\"},\"href\":null,\"doc\":null},\"content\":{\"kind\":\"doc_entry\",\"content\":[{\"name_prefix\":null,\"name\":null,\"name_href\":null,\"content\":\"<a href=\\\"../././~/Middleware.html\\\" class=\\\"link td-ref\\\">Middleware</a>\",\"anchor\":{\"id\":\"function_createpipeline_0_return\"},\"tags\":[],\"js_doc\":null,\"source_href\":null}]}}]}}]}}],\"deprecated\":null,\"source_href\":null}],\"diff_status\":{\"kind\":\"added\"}},\"breadcrumbs_ctx\":{\"root\":{\"name\":\"index\",\"href\":\"../\"},\"current_entrypoint\":{\"name\":\"default\",\"href\":\"../\"},\"entrypoints\":[{\"name\":\"all symbols\",\"href\":\".././all_symbols.html\"},{\"name\":\"default\",\"href\":\"../\"}],\"symbol\":[{\"name\":\"createPipeline\",\"href\":\"../././~/createPipeline.html\"}]},\"toc_ctx\":{\"usages\":{\"usages\":[{\"name\":\"\",\"content\":\"<div class=\\\"markdown\\\"><pre class=\\\"highlight\\\"><code class=\\\"language-typescript\\\">import { createPipeline } from &quot;.&quot;;\\n</code><button class=\\\"copyButton\\\" data-copy=\\\"import { createPipeline } from &quot;.&quot;;\\n\\\"><svg\\n class=\\\"copy\\\"\\n width=\\\"15\\\"\\n height=\\\"15\\\"\\n viewBox=\\\"0 0 15 15\\\"\\n fill=\\\"none\\\"\\n xmlns=\\\"http://www.w3.org/2000/svg\\\"\\n>\\n <rect x=\\\"2\\\" y=\\\"2\\\" width=\\\"7\\\" height=\\\"7\\\" fill=\\\"none\\\" />\\n <rect x=\\\"6\\\" y=\\\"6\\\" width=\\\"7\\\" height=\\\"7\\\" fill=\\\"none\\\" />\\n <path\\n d=\\\"M1.55566 2.7C1.55566 2.03726 2.09292 1.5 2.75566 1.5H8.75566C9.41841 1.5 9.95566 2.03726 9.95566 2.7V5.1H12.3557C13.0184 5.1 13.5557 5.63726 13.5557 6.3V12.3C13.5557 12.9627 13.0184 13.5 12.3557 13.5H6.35566C5.69292 13.5 5.15566 12.9627 5.15566 12.3V9.9H2.75566C2.09292 9.9 1.55566 9.36274 1.55566 8.7V2.7ZM6.35566 9.9V12.3H12.3557V6.3H9.95566V8.7C9.95566 9.36274 9.41841 9.9 8.75566 9.9H6.35566ZM8.75566 8.7V2.7H2.75566V8.7H8.75566Z\\\"\\n fill=\\\"currentColor\\\"\\n />\\n</svg>\\n<svg\\n class=\\\"check\\\"\\n width=\\\"15\\\"\\n height=\\\"15\\\"\\n viewBox=\\\"0 0 24 24\\\"\\n stroke-width=\\\"2\\\"\\n stroke=\\\"currentColor\\\"\\n fill=\\\"none\\\"\\n stroke-linecap=\\\"round\\\"\\n stroke-linejoin=\\\"round\\\"\\n xmlns=\\\"http://www.w3.org/2000/svg\\\"\\n>\\n <path stroke=\\\"none\\\" d=\\\"M0 0h24v24H0z\\\" fill=\\\"none\\\" />\\n <path d=\\\"M5 12l5 5l10 -10\\\" />\\n</svg>\\n</button><code></code></pre>\\n</div>\",\"icon\":null,\"additional_css\":\"\"}],\"composed\":false},\"top_symbols\":null,\"document_navigation_str\":\"<ul><li><a href=\\\"#parameters\\\" title=\\\"Parameters\\\">Parameters</a></li><li><ul><li><a href=\\\"#function_createpipeline_0_parameter____middlewares\\\" title=\\\"&lt;span&gt;...middlewares&lt;/span&gt;\\\"><span>...middlewares</span></a></li></ul></li><li><a href=\\\"#return-type\\\" title=\\\"Return Type\\\">Return Type</a></li></ul>\",\"document_navigation\":[{\"level\":1,\"content\":\"Parameters\",\"anchor\":\"parameters\"},{\"level\":2,\"content\":\"<span>...middlewares</span>\",\"anchor\":\"function_createpipeline_0_parameter____middlewares\"},{\"level\":1,\"content\":\"Return Type\",\"anchor\":\"return-type\"}]},\"disable_search\":false,\"categories_panel\":null}"
"{\"kind\":\"SymbolPageCtx\",\"html_head_ctx\":{\"title\":\"createPipeline - default - documentation\",\"current_file\":\".\",\"stylesheet_url\":\"../styles.css\",\"page_stylesheet_url\":\"../page.css\",\"reset_stylesheet_url\":\"../reset.css\",\"url_search_index\":\"../search_index.js\",\"script_js\":\"../script.js\",\"fuse_js\":\"../fuse.js\",\"search_js\":\"../search.js\",\"darkmode_toggle_js\":\"../darkmode_toggle.js\",\"head_inject\":null,\"disable_search\":false},\"symbol_group_ctx\":{\"name\":\"createPipeline\",\"symbols\":[{\"kind\":{\"kind\":\"Function\",\"char\":\"f\",\"title\":\"Function\",\"title_lowercase\":\"function\",\"title_plural\":\"Functions\"},\"usage\":null,\"tags\":[],\"subtitle\":null,\"content\":[{\"kind\":\"function\",\"value\":{\"functions\":[{\"anchor\":{\"id\":\"function_createpipeline_0\"},\"name\":\"createPipeline\",\"summary\":\"(<span><span><span>...middlewares</span><span>: <a href=\\\"../././~/Middleware.html\\\" class=\\\"link td-ref\\\">Middleware</a>[]</span></span></span>)<span>: <a href=\\\"../././~/Middleware.html\\\" class=\\\"link td-ref\\\">Middleware</a></span>\",\"deprecated\":null,\"content\":{\"id\":\"\",\"docs\":\"<div class=\\\"markdown\\\"><p>Create middleware pipeline.</p>\\n</div>\",\"sections\":[{\"header\":{\"title\":\"Parameters\",\"anchor\":{\"id\":\"parameters\"},\"href\":null,\"doc\":null},\"content\":{\"kind\":\"doc_entry\",\"content\":[{\"name_prefix\":null,\"name\":\"<span>...middlewares</span>\",\"name_href\":null,\"content\":\"<span>: <a href=\\\"../././~/Middleware.html\\\" class=\\\"link td-ref\\\">Middleware</a>[]</span>\",\"anchor\":{\"id\":\"function_createpipeline_0_parameter____middlewares\"},\"tags\":[],\"js_doc\":\"<div class=\\\"markdown\\\"><p>The middleware chain.</p>\\n</div>\",\"source_href\":null}]}},{\"header\":{\"title\":\"Return Type\",\"anchor\":{\"id\":\"return-type\"},\"href\":null,\"doc\":null},\"content\":{\"kind\":\"doc_entry\",\"content\":[{\"name_prefix\":null,\"name\":null,\"name_href\":null,\"content\":\"<a href=\\\"../././~/Middleware.html\\\" class=\\\"link td-ref\\\">Middleware</a>\",\"anchor\":{\"id\":\"function_createpipeline_0_return\"},\"tags\":[],\"js_doc\":null,\"source_href\":null}]}}]}}]}}],\"deprecated\":null,\"source_href\":null}],\"diff_status\":{\"kind\":\"added\"}},\"breadcrumbs_ctx\":{\"root\":{\"name\":\"index\",\"href\":\"../\"},\"current_entrypoint\":{\"name\":\"default\",\"href\":\"../\"},\"entrypoints\":[{\"name\":\"all symbols\",\"href\":\".././all_symbols.html\"},{\"name\":\"default\",\"href\":\"../\"}],\"symbol\":[{\"name\":\"createPipeline\",\"href\":\"../././~/createPipeline.html\"}]},\"toc_ctx\":{\"usages\":{\"usages\":[{\"name\":\"\",\"content\":\"<div class=\\\"markdown\\\"><pre class=\\\"highlight\\\"><code class=\\\"language-typescript\\\">import { createPipeline } from &quot;.&quot;;\\n</code><button class=\\\"copyButton\\\" data-copy=\\\"import { createPipeline } from &quot;.&quot;;\\n\\\"><svg\\n class=\\\"copy\\\"\\n width=\\\"15\\\"\\n height=\\\"15\\\"\\n viewBox=\\\"0 0 15 15\\\"\\n fill=\\\"none\\\"\\n xmlns=\\\"http://www.w3.org/2000/svg\\\"\\n>\\n <rect x=\\\"2\\\" y=\\\"2\\\" width=\\\"7\\\" height=\\\"7\\\" fill=\\\"none\\\" />\\n <rect x=\\\"6\\\" y=\\\"6\\\" width=\\\"7\\\" height=\\\"7\\\" fill=\\\"none\\\" />\\n <path\\n d=\\\"M1.55566 2.7C1.55566 2.03726 2.09292 1.5 2.75566 1.5H8.75566C9.41841 1.5 9.95566 2.03726 9.95566 2.7V5.1H12.3557C13.0184 5.1 13.5557 5.63726 13.5557 6.3V12.3C13.5557 12.9627 13.0184 13.5 12.3557 13.5H6.35566C5.69292 13.5 5.15566 12.9627 5.15566 12.3V9.9H2.75566C2.09292 9.9 1.55566 9.36274 1.55566 8.7V2.7ZM6.35566 9.9V12.3H12.3557V6.3H9.95566V8.7C9.95566 9.36274 9.41841 9.9 8.75566 9.9H6.35566ZM8.75566 8.7V2.7H2.75566V8.7H8.75566Z\\\"\\n fill=\\\"currentColor\\\"\\n />\\n</svg>\\n<svg\\n class=\\\"check\\\"\\n width=\\\"15\\\"\\n height=\\\"15\\\"\\n viewBox=\\\"0 0 24 24\\\"\\n stroke-width=\\\"2\\\"\\n stroke=\\\"currentColor\\\"\\n fill=\\\"none\\\"\\n stroke-linecap=\\\"round\\\"\\n stroke-linejoin=\\\"round\\\"\\n xmlns=\\\"http://www.w3.org/2000/svg\\\"\\n>\\n <path stroke=\\\"none\\\" d=\\\"M0 0h24v24H0z\\\" fill=\\\"none\\\" />\\n <path d=\\\"M5 12l5 5l10 -10\\\" />\\n</svg>\\n</button><code></code></pre>\\n</div>\",\"icon\":null,\"additional_css\":\"\"}],\"composed\":false},\"top_symbols\":null,\"document_navigation_str\":\"<ul><li><a href=\\\"#parameters\\\" title=\\\"Parameters\\\">Parameters</a></li><li><ul><li><a href=\\\"#function_createpipeline_0_parameter____middlewares\\\" title=\\\"&lt;span&gt;...middlewares&lt;/span&gt;\\\"><span>...middlewares</span></a></li></ul></li><li><a href=\\\"#return-type\\\" title=\\\"Return Type\\\">Return Type</a></li></ul>\",\"document_navigation\":[{\"level\":1,\"content\":\"Parameters\",\"anchor\":\"parameters\"},{\"level\":2,\"content\":\"<span>...middlewares</span>\",\"anchor\":\"function_createpipeline_0_parameter____middlewares\"},{\"level\":1,\"content\":\"Return Type\",\"anchor\":\"return-type\"}]},\"disable_search\":false,\"categories_panel\":null}"
],
[
"./~/debugLog.json",
Expand Down
Loading
Loading