UNPKG

eslint-plugin-jsdoc

Version:
202 lines (170 loc) 6.87 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _jsdoctypeparser = require("jsdoctypeparser"); var _lodash = _interopRequireDefault(require("lodash")); var _getJSDocComment = require("../eslint/getJSDocComment"); var _iterateJsdoc = _interopRequireWildcard(require("../iterateJsdoc")); var _jsdocUtils = _interopRequireDefault(require("../jsdocUtils")); function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const extraTypes = ['null', 'undefined', 'void', 'string', 'boolean', 'object', 'function', 'symbol', 'number', 'bigint', 'NaN', 'Infinity', 'any', '*', 'this', 'true', 'false', 'Array', 'Object', 'RegExp', 'Date', 'Function']; const stripPseudoTypes = str => { return str && str.replace(/(?:\.|<>|\.<>|\[\])$/u, ''); }; var _default = (0, _iterateJsdoc.default)(({ context, node, report, settings, sourceCode, utils }) => { var _globalScope$childSco; const { scopeManager } = sourceCode; const { globalScope } = scopeManager; const { definedTypes = [] } = context.options[0] || {}; let definedPreferredTypes = []; const { preferredTypes, structuredTags, mode } = settings; if (Object.keys(preferredTypes).length) { definedPreferredTypes = Object.values(preferredTypes).map(preferredType => { if (typeof preferredType === 'string') { // May become an empty string but will be filtered out below return stripPseudoTypes(preferredType); } if (!preferredType) { return undefined; } if (typeof preferredType !== 'object') { utils.reportSettings('Invalid `settings.jsdoc.preferredTypes`. Values must be falsy, a string, or an object.'); } return stripPseudoTypes(preferredType.replacement); }).filter(preferredType => { return preferredType; }); } const typedefDeclarations = (0, _lodash.default)(context.getAllComments()).filter(comment => { return comment.value.startsWith('*'); }).map(commentNode => { return (0, _iterateJsdoc.parseComment)(commentNode, ''); }).flatMap(doc => { return doc.tags.filter(({ tag }) => { return utils.isNamepathDefiningTag(tag); }); }).map(tag => { return tag.name; }).value(); const ancestorNodes = []; let currentScope = scopeManager.acquire(node); while (currentScope && currentScope.block.type !== 'Program') { ancestorNodes.push(currentScope.block); currentScope = currentScope.upper; } // `currentScope` may be `null` or `Program`, so in such a case, // we look to present tags instead let templateTags = ancestorNodes.length ? (0, _lodash.default)(ancestorNodes).flatMap(ancestorNode => { const commentNode = (0, _getJSDocComment.getJSDocComment)(sourceCode, ancestorNode, settings); if (!commentNode) { return []; } const jsdoc = (0, _iterateJsdoc.parseComment)(commentNode, ''); return _jsdocUtils.default.filterTags(jsdoc.tags, tag => { return 'template' === tag.tag; }); }).value() : utils.getPresentTags('template'); const classJsdoc = utils.getClassJsdoc(); if (classJsdoc !== null && classJsdoc !== void 0 && classJsdoc.tags) { templateTags = templateTags.concat(classJsdoc.tags.filter(({ tag }) => { return tag === 'template'; })); } const closureGenericTypes = _lodash.default.flatMap(templateTags, tag => { return utils.parseClosureTemplateTag(tag); }); // In modules, including Node, there is a global scope at top with the // Program scope inside const cjsOrESMScope = ((_globalScope$childSco = globalScope.childScopes[0]) === null || _globalScope$childSco === void 0 ? void 0 : _globalScope$childSco.block.type) === 'Program'; const allDefinedTypes = new Set(globalScope.variables.map(({ name }) => { return name; }) // If the file is a module, concat the variables from the module scope. .concat(cjsOrESMScope ? _lodash.default.flatMap(globalScope.childScopes, ({ variables }) => { return variables; }, []).map(({ name }) => { return name; }) : []).concat(extraTypes).concat(typedefDeclarations).concat(definedTypes).concat(definedPreferredTypes).concat(settings.mode === 'jsdoc' ? [] : closureGenericTypes)); const jsdocTagsWithPossibleType = utils.filterTags(({ tag }) => { return utils.tagMightHaveTypePosition(tag); }); jsdocTagsWithPossibleType.forEach(tag => { let parsedType; try { parsedType = (0, _jsdoctypeparser.parse)(tag.type, { mode }); } catch { // On syntax error, will be handled by valid-types. return; } (0, _jsdoctypeparser.traverse)(parsedType, ({ type, name }) => { if (type === 'NAME') { var _structuredTags$tag$t; const structuredTypes = (_structuredTags$tag$t = structuredTags[tag.tag]) === null || _structuredTags$tag$t === void 0 ? void 0 : _structuredTags$tag$t.type; if (!allDefinedTypes.has(name) && (!Array.isArray(structuredTypes) || !structuredTypes.includes(name))) { report(`The type '${name}' is undefined.`, null, tag); } else if (!extraTypes.includes(name)) { context.markVariableAsUsed(name); } } }); }); }, { iterateAllJsdocs: true, meta: { docs: { description: 'Checks that types in jsdoc comments are defined.', url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-no-undefined-types' }, schema: [{ additionalProperties: false, properties: { definedTypes: { items: { type: 'string' }, type: 'array' } }, type: 'object' }], type: 'suggestion' } }); exports.default = _default; module.exports = exports.default; //# sourceMappingURL=noUndefinedTypes.js.map