blob: 3736b4814bdcad9da3b23607473b20d08f64b6a0 [file] [log] [blame]
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _lodash = _interopRequireDefault(require("lodash"));
var _jsdoctypeparser = require("jsdoctypeparser");
var _iterateJsdoc = _interopRequireWildcard(require("../iterateJsdoc"));
var _jsdocUtils = _interopRequireDefault(require("../jsdocUtils"));
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { 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', '*', 'Array', 'Object', 'RegExp', 'Date', 'Function'];
const stripPseudoTypes = str => {
return str && str.replace(/(?:\.|<>|\.<>|\[\])$/u, '');
};
var _default = (0, _iterateJsdoc.default)(({
context,
report,
settings,
sourceCode: {
scopeManager
},
utils
}) => {
const globalScope = scopeManager.globalScope;
const _ref = context.options[0] || {},
_ref$definedTypes = _ref.definedTypes,
definedTypes = _ref$definedTypes === void 0 ? [] : _ref$definedTypes;
let definedPreferredTypes = [];
const preferredTypes = settings.preferredTypes;
if (Object.keys(preferredTypes).length) {
// Replace `_.values` with `Object.values` when we may start requiring Node 7+
definedPreferredTypes = _lodash.default.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(_iterateJsdoc.parseComment).flatMap(doc => {
return (doc.tags || []).filter(({
tag
}) => {
return utils.isNamepathDefiningTag(tag);
});
}).map(tag => {
return tag.name;
}).value();
let templateTags = utils.getPresentTags('template');
const classJsdoc = utils.getClassJsdoc();
if (classJsdoc && classJsdoc.tags) {
templateTags = templateTags.concat(classJsdoc.tags.filter(tag => {
return tag.tag === 'template';
}));
}
const closureGenericTypes = _lodash.default.flatMap(templateTags, tag => {
return _jsdocUtils.default.parseClosureTemplateTag(tag);
});
const allDefinedTypes = globalScope.variables.map(variable => {
return variable.name;
}) // If the file is a module, concat the variables from the module scope.
.concat( // This covers `commonjs` as well as `node`
scopeManager.__options.nodejsScope || scopeManager.isModule() ? globalScope.childScopes.reduce((arr, {
variables
}) => {
// Flatten
arr.push(...variables);
return arr;
}, []).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.tag);
});
jsdocTagsWithPossibleType.forEach(tag => {
let parsedType;
try {
parsedType = (0, _jsdoctypeparser.parse)(tag.type);
} catch (error) {
// On syntax error, will be handled by valid-types.
return;
}
(0, _jsdoctypeparser.traverse)(parsedType, ({
type,
name
}) => {
if (type === 'NAME') {
if (!allDefinedTypes.includes(name)) {
report(`The type '${name}' is undefined.`, null, tag);
} else if (!_lodash.default.includes(extraTypes, name)) {
context.markVariableAsUsed(name);
}
}
});
});
}, {
iterateAllJsdocs: true,
meta: {
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