From 03d3f40551bfb7cc13f00677e38baff83d13c9f4 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Mon, 17 May 2021 00:59:01 +0800 Subject: [PATCH] feat(`multiline-blocks`): add `noFinalLineText` option; fixes #738 --- .README/rules/multiline-blocks.md | 11 +++++- README.md | 33 +++++++++++++++- src/rules/multilineBlocks.js | 48 +++++++++++++++++++++-- test/rules/assertions/multilineBlocks.js | 44 +++++++++++++++++++++ test/rules/assertions/noMultiAsterisks.js | 23 +++++++++++ 5 files changed, 153 insertions(+), 6 deletions(-) diff --git a/.README/rules/multiline-blocks.md b/.README/rules/multiline-blocks.md index 74f3b49f8..812495208 100644 --- a/.README/rules/multiline-blocks.md +++ b/.README/rules/multiline-blocks.md @@ -7,6 +7,8 @@ Note that if you set `noSingleLineBlocks` and `noMultilineBlocks` to `true` and configure them in a certain manner, you might effectively be prohibiting all jsdoc blocks! +Also allows for preventing text at the very beginning or very end of blocks. + #### Options A single options object with the following properties. @@ -18,6 +20,13 @@ space will be reported. (Text after a newline is not reported.) `noMultilineBlocks` will have priority over this rule if it applies. +##### `noFinalLineText` (defaults to `true`) + +For multiline blocks, any non-whitespace text preceding the `*/` on the final +line will be reported. (Text preceding a newline is not reported.) + +`noMultilineBlocks` will have priority over this rule if it applies. + ##### `noSingleLineBlocks` (defaults to `false`) If this is `true`, any single line blocks will be reported, except those which @@ -79,6 +88,6 @@ cannot be reliably added after the tag either). |Tags|Any (though `singleLineTags` and `multilineTags` control the application)| |Recommended|true| |Settings|| -|Options|`noZeroLineText`, `noSingleLineBlocks`, `singleLineTags`, `noMultilineBlocks`, `minimumLengthForMultiline`, `multilineTags`, `allowMultipleTags`| +|Options|`noZeroLineText`, `noSingleLineBlocks`, `singleLineTags`, `noMultilineBlocks`, `minimumLengthForMultiline`, `multilineTags`, `allowMultipleTags`, `noFinalLineText`| diff --git a/README.md b/README.md index c7a3026f5..f53537a0f 100644 --- a/README.md +++ b/README.md @@ -7138,6 +7138,8 @@ Note that if you set `noSingleLineBlocks` and `noMultilineBlocks` to `true` and configure them in a certain manner, you might effectively be prohibiting all jsdoc blocks! +Also allows for preventing text at the very beginning or very end of blocks. + #### Options @@ -7151,6 +7153,14 @@ space will be reported. (Text after a newline is not reported.) `noMultilineBlocks` will have priority over this rule if it applies. + +##### noFinalLineText (defaults to true) + +For multiline blocks, any non-whitespace text preceding the `*/` on the final +line will be reported. (Text preceding a newline is not reported.) + +`noMultilineBlocks` will have priority over this rule if it applies. + ##### noSingleLineBlocks (defaults to false) @@ -7218,7 +7228,7 @@ cannot be reliably added after the tag either). |Tags|Any (though `singleLineTags` and `multilineTags` control the application)| |Recommended|true| |Settings|| -|Options|`noZeroLineText`, `noSingleLineBlocks`, `singleLineTags`, `noMultilineBlocks`, `minimumLengthForMultiline`, `multilineTags`, `allowMultipleTags`| +|Options|`noZeroLineText`, `noSingleLineBlocks`, `singleLineTags`, `noMultilineBlocks`, `minimumLengthForMultiline`, `multilineTags`, `allowMultipleTags`, `noFinalLineText`| The following patterns are considered problems: @@ -7367,6 +7377,16 @@ The following patterns are considered problems: * line. */ // "jsdoc/multiline-blocks": ["error"|"warn", {"multilineTags":[],"noMultilineBlocks":true}] // Message: Multiline jsdoc blocks are prohibited by your configuration. + +/** + * @someTag {aType} with Description */ +// "jsdoc/multiline-blocks": ["error"|"warn", {"noFinalLineBlocks":true}] +// Message: Should have no text on the final line (before the `*/`). + +/** + * Description */ +// "jsdoc/multiline-blocks": ["error"|"warn", {"noFinalLineBlocks":true}] +// Message: Should have no text on the final line (before the `*/`). ```` The following patterns are not considered problems: @@ -7469,6 +7489,9 @@ The following patterns are not considered problems: * @oneTag */ // "jsdoc/multiline-blocks": ["error"|"warn", {"allowMultipleTags":false,"multilineTags":["oneTag"],"noMultilineBlocks":true}] + +/** @someTag with Description */ +// "jsdoc/multiline-blocks": ["error"|"warn", {"noFinalLineBlocks":true}] ```` @@ -8293,6 +8316,14 @@ The following patterns are considered problems: /** abc * */ // Message: Should be no multiple asterisks on end lines. + +/** + * Preserve user's whitespace when fixing (though one may also + * use an align rule) + * + * */ +// "jsdoc/no-multi-asterisks": ["error"|"warn", {"preventAtEnd":true}] +// Message: Should be no multiple asterisks on end lines. ```` The following patterns are not considered problems: diff --git a/src/rules/multilineBlocks.js b/src/rules/multilineBlocks.js index 52f65d5e6..b032d8ad7 100644 --- a/src/rules/multilineBlocks.js +++ b/src/rules/multilineBlocks.js @@ -8,6 +8,7 @@ export default iterateJsdoc(({ }) => { const { allowMultipleTags = true, + noFinalLineText = true, noZeroLineText = true, noSingleLineBlocks = false, singleLineTags = ['lends', 'type'], @@ -96,7 +97,7 @@ export default iterateJsdoc(({ return; } - const checkZeroLineText = () => { + const lineChecks = () => { if ( noZeroLineText && (tag || description) @@ -111,6 +112,42 @@ export default iterateJsdoc(({ 'Should have no text on the "0th" line (after the `/**`).', null, fixer, ); + + return; + } + + const finalLine = jsdoc.source[jsdoc.source.length - 1]; + const finalLineTokens = finalLine.tokens; + if ( + noFinalLineText && + finalLineTokens.description.trim() + ) { + const fixer = () => { + const line = {...finalLineTokens}; + line.description = line.description.trimEnd(); + + const {delimiter} = line; + + [ + 'delimiter', + 'postDelimiter', + 'tag', + 'type', + 'postType', + 'postTag', + 'name', + 'postName', + 'description', + ].forEach((prop) => { + finalLineTokens[prop] = ''; + }); + + utils.addLine(jsdoc.source.length - 1, {...line, delimiter, end: ''}); + }; + utils.reportJSDoc( + 'Should have no text on the final line (before the `*/`).', + null, fixer, + ); } }; @@ -119,13 +156,13 @@ export default iterateJsdoc(({ jsdoc.tags.length && (multilineTags.includes('*') || utils.hasATag(multilineTags)) ) { - checkZeroLineText(); + lineChecks(); return; } if (jsdoc.description.length >= minimumLengthForMultiline) { - checkZeroLineText(); + lineChecks(); return; } @@ -222,7 +259,7 @@ export default iterateJsdoc(({ } } - checkZeroLineText(); + lineChecks(); }, { iterateAllJsdocs: true, meta: { @@ -254,6 +291,9 @@ export default iterateJsdoc(({ }, ], }, + noFinalLineText: { + type: 'boolean', + }, noMultilineBlocks: { type: 'boolean', }, diff --git a/test/rules/assertions/multilineBlocks.js b/test/rules/assertions/multilineBlocks.js index 5617f6ad7..1f07392a7 100644 --- a/test/rules/assertions/multilineBlocks.js +++ b/test/rules/assertions/multilineBlocks.js @@ -467,6 +467,42 @@ export default { /** @lends This can be safely fixed to a single line. */ `, }, + { + code: ` + /** + * @someTag {aType} with Description */ + `, + errors: [{ + line: 2, + message: 'Should have no text on the final line (before the `*/`).', + }], + options: [{ + noFinalLineBlocks: true, + }], + output: ` + /** + * @someTag {aType} with Description + */ + `, + }, + { + code: ` + /** + * Description */ + `, + errors: [{ + line: 2, + message: 'Should have no text on the final line (before the `*/`).', + }], + options: [{ + noFinalLineBlocks: true, + }], + output: ` + /** + * Description + */ + `, + }, ], valid: [ { @@ -685,5 +721,13 @@ export default { noMultilineBlocks: true, }], }, + { + code: ` + /** @someTag with Description */ + `, + options: [{ + noFinalLineBlocks: true, + }], + }, ], }; diff --git a/test/rules/assertions/noMultiAsterisks.js b/test/rules/assertions/noMultiAsterisks.js index 278ad2d40..e73f0da0a 100644 --- a/test/rules/assertions/noMultiAsterisks.js +++ b/test/rules/assertions/noMultiAsterisks.js @@ -215,6 +215,29 @@ export default { /** abc */ `, }, + { + code: ` + /** + * Preserve user's whitespace when fixing (though one may also + * use an align rule) + * + * */ + `, + errors: [{ + line: 6, + message: 'Should be no multiple asterisks on end lines.', + }], + options: [{ + preventAtEnd: true, + }], + output: ` + /** + * Preserve user's whitespace when fixing (though one may also + * use an align rule) + * + */ + `, + }, ], valid: [ {