{"version":3,"file":"requireTemplate.cjs","names":["iterateJsdoc","tryParseType","parseType","traverse"],"sources":["../../src/rules/requireTemplate.js"],"sourcesContent":["import iterateJsdoc from '../iterateJsdoc.js';\nimport {\n  parse as parseType,\n  traverse,\n  tryParse as tryParseType,\n} from '@es-joy/jsdoccomment';\n\nexport default iterateJsdoc(({\n  context,\n  node,\n  report,\n  settings,\n  utils,\n}) => {\n  if (utils.avoidDocs()) {\n    return;\n  }\n\n  const {\n    requireSeparateTemplates = false,\n  } = context.options[0] || {};\n\n  const {\n    mode,\n  } = settings;\n\n  const usedNames = new Set();\n\n  const tgName = /** @type {string} */ (utils.getPreferredTagName({\n    tagName: 'template',\n  }));\n  if (!tgName) {\n    return;\n  }\n\n  const templateTags = utils.getTags(tgName);\n\n  const templateNames = templateTags.flatMap((tag) => {\n    return utils.parseClosureTemplateTag(tag);\n  });\n\n  if (requireSeparateTemplates) {\n    for (const tag of templateTags) {\n      const names = utils.parseClosureTemplateTag(tag);\n      if (names.length > 1) {\n        report(`Missing separate @${tgName} for ${names[1]}`, null, tag);\n      }\n    }\n  }\n\n  /**\n   * @param {import('@typescript-eslint/types').TSESTree.FunctionDeclaration|\n   *   import('@typescript-eslint/types').TSESTree.ClassDeclaration|\n   *   import('@typescript-eslint/types').TSESTree.TSDeclareFunction|\n   *   import('@typescript-eslint/types').TSESTree.TSInterfaceDeclaration|\n   *   import('@typescript-eslint/types').TSESTree.TSTypeAliasDeclaration} aliasDeclaration\n   */\n  const checkTypeParams = (aliasDeclaration) => {\n    const {\n      params,\n      /* c8 ignore next -- Guard */\n    } = aliasDeclaration.typeParameters ?? {\n      /* c8 ignore next -- Guard */\n      params: [],\n    };\n    for (const {\n      name: {\n        name,\n      },\n    } of params) {\n      usedNames.add(name);\n    }\n\n    for (const usedName of usedNames) {\n      if (!templateNames.includes(usedName)) {\n        report(`Missing @${tgName} ${usedName}`);\n      }\n    }\n  };\n\n  const handleTypes = () => {\n    const nde = /** @type {import('@typescript-eslint/types').TSESTree.Node} */ (\n      node\n    );\n    if (!nde) {\n      return;\n    }\n\n    switch (nde.type) {\n      case 'ClassDeclaration':\n      case 'FunctionDeclaration':\n      case 'TSDeclareFunction':\n      case 'TSInterfaceDeclaration':\n      case 'TSTypeAliasDeclaration':\n        checkTypeParams(nde);\n        break;\n      case 'ExportDefaultDeclaration':\n        switch (nde.declaration?.type) {\n          case 'ClassDeclaration':\n          case 'FunctionDeclaration':\n          case 'TSInterfaceDeclaration':\n            checkTypeParams(nde.declaration);\n            break;\n        }\n\n        break;\n      case 'ExportNamedDeclaration':\n        switch (nde.declaration?.type) {\n          case 'ClassDeclaration':\n          case 'FunctionDeclaration':\n          case 'TSDeclareFunction':\n          case 'TSInterfaceDeclaration':\n          case 'TSTypeAliasDeclaration':\n            checkTypeParams(nde.declaration);\n            break;\n        }\n\n        break;\n    }\n  };\n\n  const usedNameToTag = new Map();\n\n  /**\n   * @param {import('comment-parser').Spec} potentialTag\n   */\n  const checkForUsedTypes = (potentialTag) => {\n    let parsedType;\n    try {\n      parsedType = mode === 'permissive' ?\n        tryParseType(/** @type {string} */ (potentialTag.type)) :\n        parseType(/** @type {string} */ (potentialTag.type), mode);\n    } catch {\n      return;\n    }\n\n    traverse(parsedType, (nde) => {\n      if (nde.type === 'JsdocTypeTypeParameter') {\n        templateNames.push(nde.name.value);\n        return;\n      }\n\n      if (nde.type === 'JsdocTypeInfer') {\n        templateNames.push(nde.element.value);\n        return;\n      }\n\n      const {\n        type,\n        value,\n      } = /** @type {import('jsdoc-type-pratt-parser').NameResult} */ (nde);\n\n      if (type === 'JsdocTypeName' && (/^[A-Z]$/v).test(value)) {\n        usedNames.add(value);\n        if (!usedNameToTag.has(value)) {\n          usedNameToTag.set(value, potentialTag);\n        }\n      }\n    });\n  };\n\n  /**\n   * @param {string[]} tagNames\n   */\n  const checkTagsAndTemplates = (tagNames) => {\n    for (const tagName of tagNames) {\n      const preferredTagName = /** @type {string} */ (utils.getPreferredTagName({\n        tagName,\n      }));\n      const matchingTags = utils.getTags(preferredTagName);\n      for (const matchingTag of matchingTags) {\n        checkForUsedTypes(matchingTag);\n      }\n    }\n\n    // Could check against whitelist/blacklist\n    for (const usedName of usedNames) {\n      if (!templateNames.includes(usedName)) {\n        report(`Missing @${tgName} ${usedName}`, null, usedNameToTag.get(usedName));\n      }\n    }\n  };\n\n  const callbackTags = utils.getTags('callback');\n  const functionTags = utils.getTags('function');\n  if (callbackTags.length || functionTags.length) {\n    checkTagsAndTemplates([\n      'param', 'returns',\n    ]);\n    return;\n  }\n\n  const typedefTags = utils.getTags('typedef');\n  if (!typedefTags.length || typedefTags.length >= 2) {\n    handleTypes();\n    return;\n  }\n\n  const potentialTypedef = typedefTags[0];\n  checkForUsedTypes(potentialTypedef);\n\n  checkTagsAndTemplates([\n    'property',\n  ]);\n}, {\n  iterateAllJsdocs: true,\n  meta: {\n    docs: {\n      description: 'Requires `@template` tags be present when type parameters are used.',\n      url: 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-template.md#repos-sticky-header',\n    },\n    schema: [\n      {\n        additionalProperties: false,\n        properties: {\n          exemptedBy: {\n            description: `Array of tags (e.g., \\`['type']\\`) whose presence on the document\nblock avoids the need for a \\`@template\\`. Defaults to an array with\n\\`inheritdoc\\`. If you set this array, it will overwrite the default,\nso be sure to add back \\`inheritdoc\\` if you wish its presence to cause\nexemption of the rule.`,\n            items: {\n              type: 'string',\n            },\n            type: 'array',\n          },\n          requireSeparateTemplates: {\n            description: `Requires that each template have its own separate line, i.e., preventing\ntemplates of this format:\n\n\\`\\`\\`js\n/**\n * @template T, U, V\n */\n\\`\\`\\`\n\nDefaults to \\`false\\`.`,\n            type: 'boolean',\n          },\n        },\n        type: 'object',\n      },\n    ],\n    type: 'suggestion',\n  },\n});\n"],"mappings":"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","ignoreList":[]}