Skip to content

Commit

Permalink
improve argument handling
Browse files Browse the repository at this point in the history
  • Loading branch information
hsjobeki committed Feb 11, 2024
1 parent de683ae commit a641949
Show file tree
Hide file tree
Showing 7 changed files with 165 additions and 57 deletions.
26 changes: 26 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,32 @@

By @hsjobeki in https://github.com/nix-community/nixdoc/pull/91

### Migration from nixdoc < 2.x.x to 3.x.x

#### Double asterisk

Comments that are intended for documentation should have `/** content */`. This allows the tool to distinguish between internal-comments and documentation comments.

#### Argument documentation

As of RFC145 specified there are is no argument documentation. For single arguments such as `a:` write the documentation into the regular content of your doc-comment.

**Example:** Single argument migration

```nix
{
/**
The id function
# Arguments
- `x` (`Any`): The provided value
*/
id = x: x;
}
```

## 2.7.0

- Added support to customise the attribute set prefix, which was previously hardcoded to `lib`.
Expand Down
15 changes: 10 additions & 5 deletions src/legacy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use rowan::ast::AstNode;
use crate::{
commonmark::{Argument, SingleArg},
format::handle_indentation,
retrieve_doc_comment,
};

/// Retrieve documentation comments.
Expand Down Expand Up @@ -67,14 +68,15 @@ pub fn retrieve_legacy_comment(node: &SyntaxNode, allow_line_comments: bool) ->
None
}

/// Traverse a Nix lambda and collect the identifiers of arguments
/// 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> {
let mut args = vec![];

loop {
match lambda.param().unwrap() {
// a variable, e.g. `id = x: x`
// a variable, e.g. `x:` in `id = x: x`
// Single args are not supported by RFC145, due to ambiguous placement rules.
Param::IdentParam(id) => {
args.push(Argument::Flat(SingleArg {
name: id.to_string(),
Expand All @@ -83,15 +85,18 @@ pub fn collect_lambda_args(mut lambda: Lambda) -> Vec<Argument> {
),
}));
}
// an attribute set, e.g. `foo = { a }: a`
// an ident in a pattern, e.g. `a` in `foo = { a }: a`
Param::Pattern(pat) => {
// collect doc-comments for each attribute in the set
// collect doc-comments for each lambda formal
// Lambda formals are supported by RFC145
let pattern_vec: Vec<_> = pat
.pat_entries()
.map(|entry| SingleArg {
name: entry.ident().unwrap().to_string(),
doc: handle_indentation(
&retrieve_legacy_comment(entry.syntax(), true).unwrap_or_default(),
&retrieve_doc_comment(&entry.syntax(), Some(1))
.or(retrieve_legacy_comment(&entry.syntax(), true))
.unwrap_or_default(),
),
})
.collect();
Expand Down
17 changes: 6 additions & 11 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,7 @@ struct DocComment {
struct DocItem {
name: String,
comment: DocComment,
// This is only filled in the legacy format
args: Vec<Argument>,
/// internal indicator if legacy features should be used.
is_legacy: bool,
}

impl DocItem {
Expand All @@ -116,7 +113,7 @@ impl DocItem {
}
}

fn retrieve_doc_comment(node: &SyntaxNode, shift_headings_by: Option<usize>) -> Option<String> {
pub fn retrieve_doc_comment(node: &SyntaxNode, shift_headings_by: Option<usize>) -> Option<String> {
// Return a rfc145 doc-comment if one is present
// Otherwise do the legacy parsing
// If there is a doc comment according to RFC145 just return it.
Expand Down Expand Up @@ -155,9 +152,12 @@ fn retrieve_doc_item(node: &AttrpathValue) -> Option<DocItem> {
match doc_comment {
Some(comment) => Some(DocItem {
name: item_name,
comment: parse_doc_comment(&comment),
comment: DocComment {
doc: comment,
doc_type: None,
example: None,
},
args: vec![],
is_legacy: false,
}),
// Fallback to legacy comment is there is no doc_comment
None => {
Expand All @@ -166,7 +166,6 @@ fn retrieve_doc_item(node: &AttrpathValue) -> Option<DocItem> {
name: item_name,
comment: parse_doc_comment(&comment),
args: vec![],
is_legacy: true,
})
}
}
Expand Down Expand Up @@ -223,10 +222,6 @@ fn parse_doc_comment(raw: &str) -> DocComment {
fn collect_entry_information(entry: AttrpathValue) -> Option<DocItem> {
let doc_item = retrieve_doc_item(&entry)?;

if !doc_item.is_legacy {
return Some(doc_item);
}

if let Some(Expr::Lambda(l)) = entry.value() {
Some(DocItem {
args: collect_lambda_args(l),
Expand Down
58 changes: 58 additions & 0 deletions src/snapshots/nixdoc__test__doc_comment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
source: src/test.rs
expression: output
---
## `lib.debug.nixdoc` {#function-library-lib.debug.nixdoc}

**Type**: `This is a parsed type`

nixdoc-legacy comment

::: {.example #function-library-example-lib.debug.nixdoc}
# `lib.debug.nixdoc` usage example

```nix
This is a parsed example
```
:::

## `lib.debug.rfc-style` {#function-library-lib.debug.rfc-style}

doc comment in markdown format


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

doc comment in markdown format

Example:

This is just markdown

Type:

This is just markdown


structured function argument

: `formal1`

: Legacy line comment

`formal2`

: Legacy Block

`formal3`

: Legacy
multiline
comment

`formal4`

: official doc-comment variant



41 changes: 31 additions & 10 deletions src/snapshots/nixdoc__test__doc_comment.snap
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,55 @@ expression: output
---
## `lib.debug.nixdoc` {#function-library-lib.debug.nixdoc}

**Type**: `This is just text`
**Type**: `This is a parsed type`

nixdoc-legacy comment

::: {.example #function-library-example-lib.debug.nixdoc}
# `lib.debug.nixdoc` usage example

```nix
This is just text
This is a parsed example
```
:::

## `lib.debug.rfc-style` {#function-library-lib.debug.rfc-style}

doc comment in markdown format

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

**Type**: `This is just text`
## `lib.debug.argumentTest` {#function-library-lib.debug.argumentTest}

doc comment in markdown format

::: {.example #function-library-example-lib.debug.arguments}
# `lib.debug.arguments` usage example
Example:

This is just markdown

Type:

This is just markdown


structured function argument

: `formal1`

: Legacy line comment

`formal2`

: Legacy Block

`formal3`

: Legacy
multiline
comment

`formal4`

: official doc-comment variant

```nix
This is just text
```
:::


34 changes: 11 additions & 23 deletions test.nix
Original file line number Diff line number Diff line change
@@ -1,49 +1,37 @@
/**
# Heading
## Implicit coercion from paths to file sets {#sec-fileset-path-coercion}
Prequel
*/
{lib}:
{

/*
/**
Create a file set from a path that may or may not exist
*/
packagesFromDirectoryRecursive =
# Options.
{
/**
`pkgs.callPackage`
rfc style
```
Path -> AttrSet -> a
```
*/
callPackage,
/**
The directory to read package files from
/*
legacy multiline
```
Path
```
*/
directory,
...
# legacy single line
config,
# legacy
# block
# comment
moreConfig,
}:
1;

/**
gitTrackedWith
*/
gitTrackedWith =
{
recurseSubmodules ? false,
}:
/*
The [path](https://nixos.org/manual/nix/stable/language/values#type-path) to the working directory of a local Git repository.
This directory must contain a `.git` file or subdirectory.
*/
path: 1;
}
31 changes: 23 additions & 8 deletions test/doc-comment.nix
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@
hidden = a: a;

/*
nixdoc-legacy comment
Example:
This is just text
This is a parsed example
Type:
This is just text
This is a parsed type
*/
nixdoc = {};

Expand All @@ -26,13 +25,29 @@
Example:
This is just text
This is just markdown
Type:
This is just text
This is just markdown
*/
arguments =
# not a doc comment
arg1: arg2: {};
argumentTest = {
# Legacy line comment
formal1,
# Legacy
# Block
formal2,
/*
Legacy
multiline
comment
*/
formal3,
/**
official doc-comment variant
*/
formal4,

}:
{};
}

0 comments on commit a641949

Please sign in to comment.