Eslint-plugin-jsdoc: Multi-line type breakage in 31

Created on 11 Jan 2021  路  13Comments  路  Source: gajus/eslint-plugin-jsdoc

Expected behavior

That tags split across multiple lines would behave as they do in 30.7.13 and before.

Actual behavior

Several rules are triggered when tags span multiple lines of a comment block prefixed with *. Examples below.

ESLint Config

{
  "extends": [
    "plugin:jsdoc/recommended"
  ]
}

ESLint sample

/** Multi-line typedef for an options object type.
 *
 * @typedef {{
 *   prop: number
 * }} MyOptions
 */

Now causes:

typedef.js:3:0: Tag @typedef must have a name/namepath in "jsdoc" mode. [Warning/jsdoc/valid-types]
/** Example with multi-line param type.
 *
 * @param {function(
 * number
 * )} cb Callback.
 */
function example(cb) {
  cb(42);
}

Now causes:

param-type.js:1:1: Missing JSDoc @param "cb" declaration. [Warning/jsdoc/require-param]
param-type.js:3:0: Expected @param names to be "cb". Got "". [Warning/jsdoc/check-param-names]
param-type.js:3:0: Missing JSDoc @param "" description. [Warning/jsdoc/require-param-description]
param-type.js:3:0: There must be an identifier after @param type. [Warning/jsdoc/require-param-name]
param-type.js:3:0: Missing JSDoc @param "" type. [Warning/jsdoc/require-param-type]
/** Example with multi-line returns type.
 *
 * @returns {!{
 * example: number
 * }} An object with an example number.
 */
function example() {
  return { example: 42 };
}

Now causes:

return-type.js:3:0: Missing JSDoc @returns description. [Warning/jsdoc/require-returns-description]
return-type.js:3:0: Missing JSDoc @returns type. [Warning/jsdoc/require-returns-type]

There are probably others. I'm not sure what restrictions JSDoc has for splitting tags across multiple lines. For what it's worth, the above examples appear to generate the same output when the lines are joined.

Also, if you'd prefer I open these as separate issues, or do a more thorough search for cases where line splitting behavior changed, let me know.

Thanks again,
Kevin

Environment

  • Node version: v12.19.0
  • ESLint version: v7.17.0
  • eslint-plugin-jsdoc version: 31.0.3
blocked bug released

Most helpful comment

Thanks again @syavorsky and @brettz9! I can confirm that 31.0.7 fixes all the occurrences of this issue that I had encountered. It's working great!

All 13 comments

One more I just noticed:

/**
 * Typedef with multi-line property type.
 *
 * @typedef {object} MyType
 * @property {function(
 * number
 * )} numberEater Method which takes a number.
 */

now causes:

prop.js:5:0: Missing JSDoc @property "" description. [Warning/jsdoc/require-property-description]
prop.js:5:0: There must be an identifier after @property type. [Warning/jsdoc/require-property-name]
prop.js:5:0: Missing JSDoc @property "" type. [Warning/jsdoc/require-property-type]

Thanks for the report. I've filed https://github.com/syavorsky/comment-parser/issues/109 as comment-parser appears to have a problem with the type portion (in curly brackets) when spanning multiple lines.

Good call. Thanks @brettz9!

:tada: This issue has been resolved in version 31.0.6 :tada:

The release is available on:

Your semantic-release bot :package::rocket:

Many thanks @syavorsky and @brettz9! Unfortunately, I don't believe all the manifestations of this JSDoc are fixed. The @returns example appears to be fixed, but I'm still getting warnings for all of the others with 31.0.6. Can you confirm?

@brettz9 let me know if there is anything else on the parser's side to be tweaked

@syavorsky : Sure, thanks...

In looking at this one, I see it is being successfully parsed with all of the expected tokens being present, but I would still expect tag.name to be filled in.

      /** Multi-line typedef for an options object type.
       *
       * @typedef {{
       *   prop: number
       * }} MyOptions
       */

After the default tag and type tokenizers, this is the output:

{
  tag: 'typedef',
  name: '',
  type: '{prop: number}',
  optional: false,
  description: '',
  problems: [],
  source: [
    { number: 2, source: '       * @typedef {{', tokens: [Object] },
    { number: 3, source: '       *   prop: number', tokens: [Object] },
    { number: 4, source: '       * }} MyOptions', tokens: [Object] },
    { number: 5, source: '       */', tokens: [Object] }
  ]
}

...and this is still the same after the default name tokenizer. (The description tokenzier thinks that MyOptions is a description, however.)

I see. Let me deal with it quickly

FWIW, I see this example appears to follow the same pattern:

    /** Example with multi-line param type.
      *
      * @param {function(
      *   number
      * )} cb Callback.
      */
      function example(cb) {
        cb(42);
      }

Before and after name tokenization:

{
  tag: 'param',
  name: '',
  type: 'function(number)',
  optional: false,
  description: '',
  problems: [],
  source: [
    {
      number: 2,
      source: '      * @param {function(',
      tokens: [Object]
    },
    { number: 3, source: '      *   number', tokens: [Object] },
    { number: 4, source: '      * )} cb Callback.', tokens: [Object] },
    { number: 5, source: '      */', tokens: [Object] }
  ]
}

@brettz9 please try with [email protected]

@syavorsky : All looks good, thanks again!

:tada: This issue has been resolved in version 31.0.7 :tada:

The release is available on:

Your semantic-release bot :package::rocket:

Thanks again @syavorsky and @brettz9! I can confirm that 31.0.7 fixes all the occurrences of this issue that I had encountered. It's working great!

Was this page helpful?
0 / 5 - 0 ratings