Skip to content

Commit

Permalink
fix(require-param): if adding params, convert single-line block to …
Browse files Browse the repository at this point in the history
…multiline; fixes #771
  • Loading branch information
brettz9 committed Jul 20, 2021
1 parent 65a473c commit 641cdee
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 57 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15179,6 +15179,10 @@ export function testFn1 ({ prop = { a: 1, b: 2 } }) {
}
// "jsdoc/require-param": ["error"|"warn", {"useDefaultObjectProperties":true}]
// Message: Missing JSDoc @param "props.prop.a" declaration.

/** Foo. */
function foo(a, b, c) {}
// Message: Missing JSDoc @param "a" declaration.
````

The following patterns are not considered problems:
Expand Down
60 changes: 60 additions & 0 deletions src/iterateJsdoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,23 @@ const getUtils = (

utils.seedTokens = seedTokens;

utils.emptyTokens = (tokens) => {
[
'start',
'postDelimiter',
'tag',
'type',
'postType',
'postTag',
'name',
'postName',
'description',
'end',
].forEach((prop) => {
tokens[prop] = '';
});
};

utils.addLine = (sourceIndex, tokens) => {
const number = (jsdoc.source[sourceIndex - 1]?.number || 0) + 1;
jsdoc.source.splice(sourceIndex, 0, {
Expand Down Expand Up @@ -300,6 +317,49 @@ const getUtils = (
});
};

utils.makeMultiline = () => {
const {source: [{tokens}]} = jsdoc;
const {postDelimiter, description, tag, name, type} = tokens;

let {tokens: {
postName, postTag, postType,
}} = jsdoc.source[0];

// Strip trailing leftovers from single line ending
if (!description) {
if (postName) {
postName = '';
} else if (postType) {
postType = '';
// eslint-disable-next-line max-len, no-inline-comments
} else /* istanbul ignore else -- `comment-parser` prevents empty blocks currently per https://github.com/syavorsky/comment-parser/issues/128 */ if (postTag) {
postTag = '';
}
}

utils.emptyTokens(tokens);

utils.addLine(1, {
delimiter: '*',

// If a description were present, it may have whitespace attached
// due to being at the end of the single line
description: description.trimEnd(),
name,
postDelimiter,
postName,
postTag,
postType,
start: indent + ' ',
tag,
type,
});
utils.addLine(2, {
end: '*/',
start: indent + ' ',
});
};

utils.flattenRoots = (params) => {
return jsdocUtils.flattenRoots(params);
};
Expand Down
60 changes: 3 additions & 57 deletions src/rules/multilineBlocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import iterateJsdoc from '../iterateJsdoc';

export default iterateJsdoc(({
context,
indent,
jsdoc,
utils,
}) => {
Expand All @@ -18,26 +17,9 @@ export default iterateJsdoc(({
} = context.options[0] || {};

const {source: [{tokens}]} = jsdoc;
const {postDelimiter, description, tag, name, type} = tokens;
const {description, tag} = tokens;
const sourceLength = jsdoc.source.length;

const emptyTokens = () => {
[
'start',
'postDelimiter',
'tag',
'type',
'postType',
'postTag',
'name',
'postName',
'description',
'end',
].forEach((prop) => {
tokens[prop] = '';
});
};

const isInvalidSingleLine = (tagName) => {
return noSingleLineBlocks &&
(!tagName ||
Expand All @@ -50,43 +32,7 @@ export default iterateJsdoc(({
}

const fixer = () => {
let {tokens: {
postName, postTag, postType,
}} = jsdoc.source[0];

// Strip trailing leftovers from single line ending
if (!description) {
if (postName) {
postName = '';
} else if (postType) {
postType = '';
// eslint-disable-next-line max-len, no-inline-comments
} else /* istanbul ignore else -- `comment-parser` prevents empty blocks currently per https://github.com/syavorsky/comment-parser/issues/128 */ if (postTag) {
postTag = '';
}
}

emptyTokens();

utils.addLine(1, {
delimiter: '*',

// If a description were present, it may have whitespace attached
// due to being at the end of the single line
description: description.trimEnd(),
name,
postDelimiter,
postName,
postTag,
postType,
start: indent + ' ',
tag,
type,
});
utils.addLine(2, {
end: '*/',
start: indent + ' ',
});
utils.makeMultiline();
};

utils.reportJSDoc(
Expand All @@ -104,7 +50,7 @@ export default iterateJsdoc(({
) {
const fixer = () => {
const line = {...tokens};
emptyTokens();
utils.emptyTokens(tokens);
const {tokens: {delimiter, start}} = jsdoc.source[1];
utils.addLine(1, {...line, delimiter, start});
};
Expand Down
3 changes: 3 additions & 0 deletions src/rules/requireParam.js
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,9 @@ export default iterateJsdoc(({
});
};

if (missingTags.length && jsdoc.source.length === 1) {
utils.makeMultiline();
}
missingTags.forEach(({functionParameterName}) => {
utils.reportJSDoc(
`Missing JSDoc @${preferredTagName} "${functionParameterName}" declaration.`,
Expand Down
26 changes: 26 additions & 0 deletions test/rules/assertions/requireParam.js
Original file line number Diff line number Diff line change
Expand Up @@ -2224,6 +2224,32 @@ export default {
sourceType: 'module',
},
},
{
code: `
/** Foo. */
function foo(a, b, c) {}
`,
errors: [
{
message: 'Missing JSDoc @param "a" declaration.',
},
{
message: 'Missing JSDoc @param "b" declaration.',
},
{
message: 'Missing JSDoc @param "c" declaration.',
},
],
output: `
/**
* Foo.
* @param a
* @param b
* @param c
*/
function foo(a, b, c) {}
`,
},
],
valid: [
{
Expand Down

0 comments on commit 641cdee

Please sign in to comment.