text: "use strict";
  
  Object.defineProperty(exports, "__esModule", {
    value: true
  });
  exports.default = void 0;
  
  var _iterateJsdoc = _interopRequireDefault(require("../iterateJsdoc"));
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  const canSkip = (utils, settings) => {
    const voidingTags = [// An abstract function is by definition incomplete
    // so it is perfectly fine if a yield is documented but
    // not present within the function.
    // A subclass may inherit the doc and implement the
    // missing yield.
    'abstract', 'virtual', // Constructor functions do not have a yield value
    //  so we can bail here, too.
    'class', 'constructor', // This seems to imply a class as well
    'interface'];
  
    if (settings.mode === 'closure') {
      // Structural Interface in GCC terms, equivalent to @interface tag as far as this rule is concerned
      voidingTags.push('record');
    }
  
    return utils.hasATag(voidingTags) || utils.isConstructor() || utils.classHasTag('interface') || settings.mode === 'closure' && utils.classHasTag('record');
  };
  
  const checkTagName = (utils, report, tagName) => {
    const preferredTagName = utils.getPreferredTagName({
      tagName
    });
  
    if (!preferredTagName) {
      return [];
    }
  
    const tags = utils.getTags(preferredTagName);
  
    if (tags.length === 0) {
      return [];
    }
  
    if (tags.length > 1) {
      report(`Found more than one @${preferredTagName} declaration.`);
      return [];
    }
  
    return [preferredTagName, tags[0]];
  };
  
  var _default = (0, _iterateJsdoc.default)(({
    context,
    report,
    settings,
    utils
  }) => {
    if (canSkip(utils, settings)) {
      return;
    }
  
    const {
      next = false,
      checkGeneratorsOnly = false
    } = context.options[0] || {};
    const [preferredYieldTagName, yieldTag] = checkTagName(utils, report, 'yields');
  
    if (preferredYieldTagName) {
      const shouldReportYields = () => {
        if (yieldTag.type.trim() === 'never') {
          if (utils.hasYieldValue()) {
            report(`JSDoc @${preferredYieldTagName} declaration set with "never" but yield expression is present in function.`);
          }
  
          return false;
        }
  
        if (checkGeneratorsOnly && !utils.isGenerator()) {
          return true;
        }
  
        return utils.hasDefinedTypeTag(yieldTag) && !utils.hasYieldValue();
      }; // In case a yield value is declared in JSDoc, we also expect one in the code.
  
  
      if (shouldReportYields()) {
        report(`JSDoc @${preferredYieldTagName} declaration present but yield expression not available in function.`);
      }
    }
  
    if (next) {
      const [preferredNextTagName, nextTag] = checkTagName(utils, report, 'next');
  
      if (preferredNextTagName) {
        const shouldReportNext = () => {
          if (nextTag.type.trim() === 'never') {
            if (utils.hasYieldReturnValue()) {
              report(`JSDoc @${preferredNextTagName} declaration set with "never" but yield expression with return value is present in function.`);
            }
  
            return false;
          }
  
          if (checkGeneratorsOnly && !utils.isGenerator()) {
            return true;
          }
  
          return utils.hasDefinedTypeTag(nextTag) && !utils.hasYieldReturnValue();
        };
  
        if (shouldReportNext()) {
          report(`JSDoc @${preferredNextTagName} declaration present but yield expression with return value not available in function.`);
        }
      }
    }
  }, {
    meta: {
      docs: {
        description: 'Requires a yield statement in function body if a `@yields` tag is specified in jsdoc comment.',
        url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-yields-check'
      },
      schema: [{
        additionalProperties: false,
        properties: {
          checkGeneratorsOnly: {
            default: false,
            type: 'boolean'
          },
          contexts: {
            items: {
              anyOf: [{
                type: 'string'
              }, {
                additionalProperties: false,
                properties: {
                  comment: {
                    type: 'string'
                  },
                  context: {
                    type: 'string'
                  }
                },
                type: 'object'
              }]
            },
            type: 'array'
          },
          exemptedBy: {
            items: {
              type: 'string'
            },
            type: 'array'
          },
          next: {
            default: false,
            type: 'boolean'
          }
        },
        type: 'object'
      }],
      type: 'suggestion'
    }
  });
  
  exports.default = _default;
  module.exports = exports.default;
  //# sourceMappingURL=requireYieldsCheck.js.map