Skip to content

Commit

Permalink
feat: add require-asterisk-prefix rule
Browse files Browse the repository at this point in the history
This rule checks that each line of the jsdoc comment starts with an asterisk. For composability with
other rules, this does not check the alignment or indentation of the comment content.

fix #199
  • Loading branch information
Eli Skeggs committed Dec 14, 2019
1 parent 6014360 commit 02a2102
Show file tree
Hide file tree
Showing 7 changed files with 181 additions and 14 deletions.
2 changes: 2 additions & 0 deletions .README/README.md
Expand Up @@ -44,6 +44,7 @@ Finally, enable all of the rules that you would like to use.
"jsdoc/check-examples": 1,
"jsdoc/check-indentation": 1,
"jsdoc/check-param-names": 1, // Recommended
"jsdoc/require-asterisk-prefix": 1,
"jsdoc/check-syntax": 1,
"jsdoc/check-tag-names": 1, // Recommended
"jsdoc/check-types": 1, // Recommended
Expand Down Expand Up @@ -337,6 +338,7 @@ only (e.g., to match `Array` if the type is `Array` vs. `Array.<string>`).
{"gitdown": "include", "file": "./rules/newline-after-description.md"}
{"gitdown": "include", "file": "./rules/no-types.md"}
{"gitdown": "include", "file": "./rules/no-undefined-types.md"}
{"gitdown": "include", "file": "./rules/require-asterisk-prefix.md"}
{"gitdown": "include", "file": "./rules/require-description-complete-sentence.md"}
{"gitdown": "include", "file": "./rules/require-description.md"}
{"gitdown": "include", "file": "./rules/require-example.md"}
Expand Down
12 changes: 12 additions & 0 deletions .README/rules/require-asterisk-prefix.md
@@ -0,0 +1,12 @@
### `require-asterisk-prefix`

Requires that each JSDoc line starts with an `*`.

#### Options

This rule allows one optional string argument. If it is `"always"` then a problem is raised when there is no asterisk prefix on a given jsdoc line. If it is `"never"` then a problem is raised when there is an asterisk present. The default value is `"always"`.

|||
|---|---|
|Context|everywhere|
|Tags|N/a|
41 changes: 29 additions & 12 deletions README.md
Expand Up @@ -34,6 +34,7 @@ JSDoc linting rules for ESLint.
* [`newline-after-description`](#eslint-plugin-jsdoc-rules-newline-after-description)
* [`no-types`](#eslint-plugin-jsdoc-rules-no-types)
* [`no-undefined-types`](#eslint-plugin-jsdoc-rules-no-undefined-types)
* [`require-asterisk-prefix`](#eslint-plugin-jsdoc-rules-require-asterisk-prefix)
* [`require-description-complete-sentence`](#eslint-plugin-jsdoc-rules-require-description-complete-sentence)
* [`require-description`](#eslint-plugin-jsdoc-rules-require-description)
* [`require-example`](#eslint-plugin-jsdoc-rules-require-example)
Expand Down Expand Up @@ -87,6 +88,7 @@ Finally, enable all of the rules that you would like to use.
"jsdoc/check-examples": 1,
"jsdoc/check-indentation": 1,
"jsdoc/check-param-names": 1, // Recommended
"jsdoc/require-asterisk-prefix": 1,
"jsdoc/check-syntax": 1,
"jsdoc/check-tag-names": 1, // Recommended
"jsdoc/check-types": 1, // Recommended
Expand Down Expand Up @@ -5107,6 +5109,21 @@ function quux () {}
````
<a name="eslint-plugin-jsdoc-rules-require-asterisk-prefix"></a>
### <code>require-asterisk-prefix</code>
Requires that each JSDoc line starts with an `*`.
<a name="eslint-plugin-jsdoc-rules-require-asterisk-prefix-options-10"></a>
#### Options
This rule allows one optional string argument. If it is `"always"` then a problem is raised when there is no asterisk prefix on a given jsdoc line. If it is `"never"` then a problem is raised when there is an asterisk present. The default value is `"always"`.
|||
|---|---|
|Context|everywhere|
|Tags|N/a|
<a name="eslint-plugin-jsdoc-rules-require-description-complete-sentence"></a>
### <code>require-description-complete-sentence</code>
Expand All @@ -5121,10 +5138,10 @@ tag descriptions are written in complete sentences, i.e.,
* A colon or semi-colon followed by two line breaks is still part of the
containing paragraph (unlike normal dual line breaks).
<a name="eslint-plugin-jsdoc-rules-require-description-complete-sentence-options-10"></a>
<a name="eslint-plugin-jsdoc-rules-require-description-complete-sentence-options-11"></a>
#### Options
<a name="eslint-plugin-jsdoc-rules-require-description-complete-sentence-options-10-tags-2"></a>
<a name="eslint-plugin-jsdoc-rules-require-description-complete-sentence-options-11-tags-2"></a>
##### <code>tags</code>
If you want additional tags to be checked for their descriptions, you may
Expand Down Expand Up @@ -5612,7 +5629,7 @@ Requires that all functions have a description.
`"tag"`) must have a non-empty description that explains the purpose of the
method.
<a name="eslint-plugin-jsdoc-rules-require-description-options-11"></a>
<a name="eslint-plugin-jsdoc-rules-require-description-options-12"></a>
#### Options
An options object may have any of the following properties:
Expand Down Expand Up @@ -5897,25 +5914,25 @@ Requires that all functions have examples.
* All functions must have one or more `@example` tags.
* Every example tag must have a non-empty description that explains the method's usage.
<a name="eslint-plugin-jsdoc-rules-require-example-options-12"></a>
<a name="eslint-plugin-jsdoc-rules-require-example-options-13"></a>
#### Options
This rule has an object option.
<a name="eslint-plugin-jsdoc-rules-require-example-options-12-exemptedby"></a>
<a name="eslint-plugin-jsdoc-rules-require-example-options-13-exemptedby"></a>
##### <code>exemptedBy</code>
Array of tags (e.g., `['type']`) whose presence on the document
block avoids the need for an `@example`. Defaults to an empty array.
<a name="eslint-plugin-jsdoc-rules-require-example-options-12-avoidexampleonconstructors"></a>
<a name="eslint-plugin-jsdoc-rules-require-example-options-13-avoidexampleonconstructors"></a>
##### <code>avoidExampleOnConstructors</code>
Set to `true` to avoid the need for an example on a constructor (whether
indicated as such by a jsdoc tag or by being within an ES6 `class`).
Defaults to `false`.
<a name="eslint-plugin-jsdoc-rules-require-example-options-12-contexts-1"></a>
<a name="eslint-plugin-jsdoc-rules-require-example-options-13-contexts-1"></a>
##### <code>contexts</code>
Set this to an array of strings representing the AST context
Expand Down Expand Up @@ -6093,7 +6110,7 @@ function quux () {
Requires a hyphen before the `@param` description.
<a name="eslint-plugin-jsdoc-rules-require-hyphen-before-param-description-options-13"></a>
<a name="eslint-plugin-jsdoc-rules-require-hyphen-before-param-description-options-14"></a>
#### Options
This rule takes one optional string argument. If it is `"always"` then a problem is raised when there is no hyphen before the description. If it is `"never"` then a problem is raised when there is a hyphen before the description. The default value is `"always"`.
Expand Down Expand Up @@ -6199,7 +6216,7 @@ function quux () {
Checks for presence of jsdoc comments, on class declarations as well as
functions.
<a name="eslint-plugin-jsdoc-rules-require-jsdoc-options-14"></a>
<a name="eslint-plugin-jsdoc-rules-require-jsdoc-options-15"></a>
#### Options
Accepts one optional options object with the following optional keys.
Expand Down Expand Up @@ -7387,7 +7404,7 @@ function quux (foo) {
Requires that all function parameters are documented.
<a name="eslint-plugin-jsdoc-rules-require-param-options-15"></a>
<a name="eslint-plugin-jsdoc-rules-require-param-options-16"></a>
#### Options
An options object accepts one optional property:
Expand Down Expand Up @@ -8487,7 +8504,7 @@ Requires returns are documented.
Will also report if multiple `@returns` tags are present.
<a name="eslint-plugin-jsdoc-rules-require-returns-options-16"></a>
<a name="eslint-plugin-jsdoc-rules-require-returns-options-17"></a>
#### Options
- `exemptedBy` - Array of tags (e.g., `['type']`) whose presence on the document
Expand Down Expand Up @@ -8952,7 +8969,7 @@ Also impacts behaviors on namepath (or event)-defining and pointing tags:
allow `#`, `.`, or `~` at the end (which is not allowed at the end of
normal paths).
<a name="eslint-plugin-jsdoc-rules-valid-types-options-17"></a>
<a name="eslint-plugin-jsdoc-rules-valid-types-options-18"></a>
#### Options
- `allowEmptyNamepaths` (default: true) - Set to `false` to disallow
Expand Down
7 changes: 5 additions & 2 deletions src/index.js
Expand Up @@ -14,13 +14,14 @@ import matchDescription from './rules/matchDescription';
import newlineAfterDescription from './rules/newlineAfterDescription';
import noTypes from './rules/noTypes';
import noUndefinedTypes from './rules/noUndefinedTypes';
import requireDescriptionCompleteSentence from './rules/requireDescriptionCompleteSentence';
import requireAsteriskPrefix from './rules/requireAsteriskPrefix';
import requireDescription from './rules/requireDescription';
import requireDescriptionCompleteSentence from './rules/requireDescriptionCompleteSentence';
import requireExample from './rules/requireExample';
import requireHyphenBeforeParamDescription from './rules/requireHyphenBeforeParamDescription';
import requireParamName from './rules/requireParamName';
import requireParam from './rules/requireParam';
import requireParamDescription from './rules/requireParamDescription';
import requireParamName from './rules/requireParamName';
import requireParamType from './rules/requireParamType';
import requireReturns from './rules/requireReturns';
import requireReturnsCheck from './rules/requireReturnsCheck';
Expand Down Expand Up @@ -49,6 +50,7 @@ export default {
'jsdoc/newline-after-description': 'warn',
'jsdoc/no-types': 'off',
'jsdoc/no-undefined-types': 'warn',
'jsdoc/require-asterisk-prefix': 'off',
'jsdoc/require-description': 'off',
'jsdoc/require-description-complete-sentence': 'off',
'jsdoc/require-example': 'off',
Expand Down Expand Up @@ -82,6 +84,7 @@ export default {
'newline-after-description': newlineAfterDescription,
'no-types': noTypes,
'no-undefined-types': noUndefinedTypes,
'require-asterisk-prefix': requireAsteriskPrefix,
'require-description': requireDescription,
'require-description-complete-sentence': requireDescriptionCompleteSentence,
'require-example': requireExample,
Expand Down
41 changes: 41 additions & 0 deletions src/rules/requireAsteriskPrefix.js
@@ -0,0 +1,41 @@
import iterateJsdoc from '../iterateJsdoc';

const prefixMatch = /^(\s+)(?:\*( ?))?/u;
const validPrefix = /^\s+\*(?:\/?$| )/u;

export default iterateJsdoc(({
sourceCode,
jsdocNode,
report,
}) => {
const fix = (fixer) => {
const replacement = sourceCode.getText(jsdocNode).split('\n')
.map((line, index) => {
return index && !validPrefix.test(line) ? line.replace(prefixMatch, (_, $1, $2) => {
return `${$1}*${$2 || ' '}`;
}) : line;
})
.join('\n');

return fixer.replaceText(jsdocNode, replacement);
};

sourceCode.getText(jsdocNode).split('\n').some((line, index) => {
const lineNum = parseInt(index, 10);
if (lineNum && !validPrefix.test(line)) {
report('Expected JSDoc block to have the prefix.', fix, {
line: lineNum,
});

return true;
}

return false;
});
}, {
iterateAllJsdocs: true,
meta: {
fixable: 'code',
type: 'layout',
},
});
91 changes: 91 additions & 0 deletions test/rules/assertions/requireAsteriskPrefix.js
@@ -0,0 +1,91 @@
export default {
invalid: [
{
code: `
/**
@param {Number} foo
*/
function quux (foo) {
// with spaces
}
`,
errors: [
{
line: 4,
message: 'Expected JSDoc block to have the prefix.',
},
],
output: `
/**
* @param {Number} foo
*/
function quux (foo) {
// with spaces
}
`,
},
{
code: `
/**
@param {Number} foo
*/function quux (foo) {
// with spaces
}
`,
errors: [
{
line: 3,
message: 'Expected JSDoc block to have the prefix.',
},
],
output: `
/**
* @param {Number} foo
*/function quux (foo) {
// with spaces
}
`,
},
],
valid: [
{
code: `
/**
* Desc
*
* @param {Number} foo
* This is more comment.
*/
function quux (foo) {
}
`,
},
{
code: `
/**
* Desc
*
* @param {{
* foo: Bar,
* bar: Baz
* }} foo
*
*/
function quux (foo) {
}
`,
},
{
code: `
/* <- JSDoc must start with 2 stars.
So this is unchecked.
*/
function quux (foo) {}
`,
},
],
};
1 change: 1 addition & 0 deletions test/rules/index.js
Expand Up @@ -23,6 +23,7 @@ const ruleTester = new RuleTester();
'newline-after-description',
'no-types',
'no-undefined-types',
'require-asterisk-prefix',
'require-description',
'require-description-complete-sentence',
'require-example',
Expand Down

0 comments on commit 02a2102

Please sign in to comment.