Abstract
Add indentation-based block comments with annotation possibilities to solve poor JS documentation adoption.
Problem
It seems, like current JS comments is not very effective and is not in wide use for writing documentation. While there are a lot of developers who try to use JSDoc to describe their APIs, there are way much more developers who don't. And I think the problem is in JS block comment peculiar properties.
There are two main problems for this technical debt, expensive doc-tools implementation for code editor developers and current JS syntax. And the first two is led by the last one. I think that JS syntax has non-obvious problems and should be updated to let this issue be solved. And these problems are in JS block comments. Here they are:
- Block comments couldn't be nested.
- Block comments couldn't include blocks of code in JS and other languages without potential harm or additional work.
- Lack of namespaces.
- No native parser.
So how this problems affect the development process.
1. Block comments couldn't be nested
Block comment couldn't be put inside another block comment. As a result we got that JSDoc code example couldn't contain multiline comments. It makes developers to write single-line comments which is very hard to keep nice-looking when you edit block of text. Newlines make you go to the line start to add comment mark.
2. Block comments couldn't include blocks of code in JS and other languages without potential harm
You couldn't just copy/paste some code as a block-comment, in the case if it contains another block-comments.. Because it will brake the source code and require developers to replace block-comments into single-line comments.
3. Lack of namespaces
There is no way to determine which comment is a JSDoc, which one is just a copyright comment or ESLint ignore sequence without parsing it and if there is a problem with parsing, we couldn't emit an error, because it's actually could be a valid comment for another tool. To determine valid JSDoc syntax, it uses asterisks as a prefixes.
4. No native parser
Native JS parser just ignores comments and wouldn't notify developer if there is a problem with provided values.
All this leads to a situation, when:
- Dev-tools developers couldn't write simple-like-a-stick utils and should know any possible exceptions and use heuristics to determine when things gone wrong.
- Editor developers couldn't create reliable tools, because there is no standard.
- Developers try to avoid writing big detailed comments, due to bunch of handwork.
- Every dev-tool developer should create a custom parser even for pretty simple DSLs.
- Dev-tools developers "fights" for global namespace and should create very complex syntax constructions to avoid conflicts.
- Malformed annotation should be always decided valid because it could belong to another tool.
- No well-known behavior to run additional checks with a simple tool or a single command.
- Developers' experience reusability is pretty low, so we don't get synergy.
Motivation
Modern languages and environments have built-in documentation generation tools. Rust and Golang code repositories contain full documentation: crates.io and pkg.go.dev. Deno also supports documentation generation out of the box.
Some languages have block comments Haskell, Elm, which can be nested and use indentation instead of charters sequence. It seems very user-friendly.
Proposal
- Add annotations which contains namespace and indentation-based block of text.
- Add indentation-based block comment.
Spec
Syntax
Annotation
= SinglelineAnnotation
| MultilineAnnotation
| CommentBlock
SinglelineAnnotation
= "{?" Tag "?}"
| "{?" Tag JSValue "?}"
MultilineAnnotation
= "{?" Tag Newline IndentBlock "?}"
| "{?" Tag JSValue Newline Block "?}"
CommentBlock
= "{?" Newline IndentBlock "?}"
Newline = "\n" | "\r\n"
Block
= Indent String Newline Block
| Indent String Newline
JSValue
is an instance of one of JS primitives: Null, Boolean, Number, String, Object, Array.
Additions
To solve conflicts in package development, annotation tag could be resolved to globally unique values:
- For Node.js
annotations
directive could be added topackage.json
to resolve annotation tags to package names. - For browser there is no need in such resolution, because annotations should be ignored in runtime.
Examples
Block Comment
Simple block comment, which shouldn't be treated as annotation or service comment:
{?
Hello this is a block comment.
It uses indentation instead of closing sequence. Thus it could be nested...
{?
...more then once. Because nested code is just a text, not a JS source.
?}
This is why such comment can contain almost anything.
?}
JSDoc
JSDoc could be used almost without changes, like this:
{? jsdoc
Add returns sum of `a` and `b`.
@param {number} a Left number
@param {number} b Right number
@returns {number} Sum of a and b
@example
add(1, 2) // -> 3
?}
function add(a, b) {
return a + b
}
Eslint
ESLint can use single-line annotations:
{? eslint.disable ["eqeqeq", "no-console"] ?}
if (x != null) {
console.log('Not null-alike')
}
Node debugger
Currently Node.js and V8 use non-standard debug keyword for debugging purposes. It could be replaced with inline annotation:
import run from './app'
{? v8.debug ?}
run()
Markdown and nesting
Safely use markdown and JS within it:
{? man
The function squares passed values:
```
// Nested annotation works fine
{? assert 4 ?}
square(2)
```
?}
function square(a) {
return a ^^ 2
}
Notes:
- Annotation is easily nested in each other. Because nested annotation is just a part of text block.
- Code editor can determine text-block highlighting mode by resolving
man
tag with some dictionary or usingpackage.json#annotations
.
File metadata
Describe file metadata:
{? meta {
authors: [{
name: "Paul Rumkin",
homepage: "https://rumk.in",
}],
date: "2021-02-02",
licens: "MIT",
tags: ["info"]
} ?}
export const authors = [{
name: "Paul Rumkin",
homepage: "https://rumk.in",
}]
Notes:
- It's possible to replace author URL in metadata without affecting the code part. This work could be automated with code.
- It's possible to add/remove/update tags assigned to source and use them for autogenerated commit messages.
- This data could be extracted by dev-tools to analyze, e.g. Github can use tags in search.
- Annotation value could be checked with JSONSchema to match the format.
Pros
- Standardized behavior helps developers to build sustainable and reliable tools.
- Other languages could be seamlessly nested in JS code.
- No escape sequences in text block simplifies manual editing.
- Namespaces solve conflicts issue.
- Annotations can help to finally solve decades-long documentation generation issue with better, simpler, and more reliable tools.
- Annotations handler could be realized as a simple function, without the need to write custom parsers in simple cases:
function annotationHandler(tag:string, param:any, block:string?) {}
- Parsing errors are generated, if annotation syntax is invalid.
Cons
- Indentation-based syntax looks heterogenous to JS.
- Indentation-based syntax cannot be minimized with current tools, so it should be removed or left unchanged.
- Inconsistent tabs/spaces might be an issue in some cases.