Skip to content

Commit

Permalink
args: omit all lamda args. To force explizit documentation of them.
Browse files Browse the repository at this point in the history
  • Loading branch information
hsjobeki committed Mar 8, 2024
1 parent e45ec5b commit 02e9910
Show file tree
Hide file tree
Showing 8 changed files with 237 additions and 72 deletions.
34 changes: 30 additions & 4 deletions src/legacy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,37 @@ use rnix::{
use rowan::ast::AstNode;

use crate::{
commonmark::{Argument, SingleArg},
commonmark::{Argument, ManualEntry, SingleArg},
format::handle_indentation,
retrieve_doc_comment,
retrieve_doc_comment, DocComment,
};

#[derive(Debug)]
pub struct LegacyDocItem {
pub name: String,
pub comment: DocComment,
pub args: Vec<Argument>,
}

impl LegacyDocItem {
pub fn into_entry(self, prefix: &str, category: &str) -> ManualEntry {
ManualEntry {
prefix: prefix.to_string(),
category: category.to_string(),
name: self.name,
description: self
.comment
.doc
.split("\n\n")
.map(|s| s.to_string())
.collect(),
fn_type: self.comment.doc_type,
example: self.comment.example,
args: self.args,
}
}
}

/// Retrieve documentation comments.
pub fn retrieve_legacy_comment(node: &SyntaxNode, allow_line_comments: bool) -> Option<String> {
// if the current node has a doc comment it'll be immediately preceded by that comment,
Expand Down Expand Up @@ -70,7 +96,7 @@ pub fn retrieve_legacy_comment(node: &SyntaxNode, allow_line_comments: bool) ->

/// Traverse directly chained nix lambdas and collect the identifiers of all lambda arguments
/// until an unexpected AST node is encountered.
pub fn collect_lambda_args(mut lambda: Lambda) -> Vec<Argument> {
pub fn collect_lambda_args_legacy(mut lambda: Lambda) -> Vec<Argument> {
let mut args = vec![];

loop {
Expand All @@ -87,7 +113,7 @@ pub fn collect_lambda_args(mut lambda: Lambda) -> Vec<Argument> {
}
// an ident in a pattern, e.g. `a` in `foo = { a }: a`
Param::Pattern(pat) => {
// collect doc-comments for each lambda formal
// collect doc-comments for each lambda formal too
// Lambda formals are supported by RFC145
let pattern_vec: Vec<_> = pat
.pat_entries()
Expand Down
70 changes: 37 additions & 33 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use crate::{format::handle_indentation, legacy::retrieve_legacy_comment};
use self::comment::get_expr_docs;
use self::commonmark::*;
use format::shift_headings;
use legacy::collect_lambda_args;
use legacy::{collect_lambda_args_legacy, LegacyDocItem};
use rnix::{
ast::{Attr, AttrpathValue, Expr, Inherit, LetIn},
SyntaxKind, SyntaxNode,
Expand Down Expand Up @@ -91,26 +91,11 @@ struct DocComment {
struct DocItem {
name: String,
comment: DocComment,
args: Vec<Argument>,
}

impl DocItem {
fn into_entry(self, prefix: &str, category: &str) -> ManualEntry {
ManualEntry {
prefix: prefix.to_string(),
category: category.to_string(),
name: self.name,
description: self
.comment
.doc
.split("\n\n")
.map(|s| s.to_string())
.collect(),
fn_type: self.comment.doc_type,
example: self.comment.example,
args: self.args,
}
}
enum DocItemOrLegacy {
LegacyDocItem(LegacyDocItem),
DocItem(DocItem),
}

/// Returns a rfc145 doc-comment if one is present
Expand All @@ -130,7 +115,7 @@ pub fn retrieve_doc_comment(node: &SyntaxNode, shift_headings_by: Option<usize>)

/// Transforms an AST node into a `DocItem` if it has a leading
/// documentation comment.
fn retrieve_doc_item(node: &AttrpathValue) -> Option<DocItem> {
fn retrieve_doc_item(node: &AttrpathValue) -> Option<DocItemOrLegacy> {
let ident = node.attrpath().unwrap();
// TODO this should join attrs() with '.' to handle whitespace, dynamic attrs and string
// attrs. none of these happen in nixpkgs lib, and the latter two should probably be
Expand All @@ -139,23 +124,22 @@ fn retrieve_doc_item(node: &AttrpathValue) -> Option<DocItem> {

let doc_comment = retrieve_doc_comment(node.syntax(), Some(2));
match doc_comment {
Some(comment) => Some(DocItem {
Some(comment) => Some(DocItemOrLegacy::DocItem(DocItem {
name: item_name,
comment: DocComment {
doc: comment,
doc_type: None,
example: None,
},
args: vec![],
}),
})),
// Fallback to legacy comment is there is no doc_comment
None => {
let comment = retrieve_legacy_comment(node.syntax(), false)?;
Some(DocItem {
Some(DocItemOrLegacy::LegacyDocItem(LegacyDocItem {
name: item_name,
comment: parse_doc_comment(&comment),
args: vec![],
})
}))
}
}
}
Expand Down Expand Up @@ -208,16 +192,36 @@ fn parse_doc_comment(raw: &str) -> DocComment {
/// 2. The attached doc comment on the entry.
/// 3. The argument names of any curried functions (pattern functions
/// not yet supported).
fn collect_entry_information(entry: AttrpathValue) -> Option<DocItem> {
fn collect_entry_information(entry: AttrpathValue) -> Option<LegacyDocItem> {
let doc_item = retrieve_doc_item(&entry)?;

if let Some(Expr::Lambda(l)) = entry.value() {
Some(DocItem {
args: collect_lambda_args(l),
..doc_item
})
} else {
Some(doc_item)
match doc_item {
DocItemOrLegacy::LegacyDocItem(v) => {
if let Some(Expr::Lambda(l)) = entry.value() {
Some(LegacyDocItem {
args: collect_lambda_args_legacy(l),
..v
})
} else {
Some(v)
}
}
// Convert DocItems into legacyItem for markdown rendering
DocItemOrLegacy::DocItem(v) => {
// if let Some(Expr::Lambda(l)) = entry.value() {
// Some(LegacyDocItem {
// args: collect_lambda_args(l),
// name: v.name,
// comment: v.comment,
// })
// } else {
// }
Some(LegacyDocItem {
args: vec![],
name: v.name,
comment: v.comment,
})
}
}
}

Expand Down
23 changes: 0 additions & 23 deletions src/snapshots/nixdoc__test__doc_comment.snap
Original file line number Diff line number Diff line change
Expand Up @@ -32,29 +32,6 @@ Type: (Should NOT be a heading)

This is just markdown

structured function argument

: `formal1`

: Legacy line comment

`formal2`

: Legacy Block

`formal3`

: Legacy
multiline
comment

`formal4`

: official doc-comment variant


## `lib.debug.foo` {#function-library-lib.debug.foo}

Comment


Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
source: src/test.rs
expression: output
---
# Debug {#sec-functions-library-debug}


## `lib.debug.old` {#function-library-lib.debug.old}

nixdoc comment

`arg`

: Should be visible


## `lib.debug.omited` {#function-library-lib.debug.omited}

Doc-comment

## `lib.debug.multiple` {#function-library-lib.debug.multiple}

Doc-comment

## `lib.debug.argumentTest` {#function-library-lib.debug.argumentTest}

Doc-comment before the lamdba causes the whole
lambda including its arguments to switch to doc-comments ONLY rendering

## `lib.debug.legacyArgumentTest` {#function-library-lib.debug.legacyArgumentTest}

Legacy comments allow to use any
form of comments for the lambda arguments/formals

structured function argument

: `formal1`

: Legacy line comment

`formal2`

: Legacy Block

`formal3`

: Legacy
multiline
comment

`formal4`

: doc-comment style
21 changes: 21 additions & 0 deletions src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,3 +179,24 @@ fn test_doc_comment_section_description() {

insta::assert_snapshot!(output);
}

#[test]
fn test_doc_comment_no_duplicate_arguments() {
let mut output = Vec::new();
let src = fs::read_to_string("test/doc-comment-arguments.nix").unwrap();
let nix = rnix::Root::parse(&src).ok().expect("failed to parse input");
let prefix = "lib";
let category = "debug";
let desc = retrieve_description(&nix, &"Debug", category);
writeln!(output, "{}", desc).expect("Failed to write header");

for entry in collect_entries(nix, prefix, category) {
entry
.write_section(&Default::default(), &mut output)
.expect("Failed to write section")
}

let output = String::from_utf8(output).expect("not utf8");

insta::assert_snapshot!(output);
}
27 changes: 27 additions & 0 deletions test.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
/** Doc comment*/
foo =
# Ignored
bar:
bar;

/**
doc comment in markdown format
Causes the whole function to use RFC145 conform rendering
*/
argumentTest =
{
# Not documented
formal1,
formal2,
/* Not documented */
formal3,
/**
Documented
*/
formal4,
}:
{};
}
69 changes: 69 additions & 0 deletions test/doc-comment-arguments.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{
/* nixdoc comment */
old =
# Should be visible
arg: 1;

/** Doc-comment */
omited =
# Not visible
arg: 1;

/** Doc-comment */
multiple =
# Not visible
arg:
/* Not visible */
foo:
/** Not visible */
bar:
1;

/**
Doc-comment before the lamdba causes the whole
lambda including its arguments to switch to doc-comments ONLY rendering
*/
argumentTest = {
# Legacy line comment
formal1,
# Legacy
# Block
formal2,
/*
Legacy
multiline
comment
*/
formal3,
/**
Not shown yet
*/
formal4,

}:
{};

/*
Legacy comments allow to use any
form of comments for the lambda arguments/formals
*/
legacyArgumentTest = {
# Legacy line comment
formal1,
# Legacy
# Block
formal2,
/*
Legacy
multiline
comment
*/
formal3,
/**
doc-comment style
*/
formal4,

}:
{};
}
Loading

0 comments on commit 02e9910

Please sign in to comment.