123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450 |
- "use strict";
-
- Object.defineProperty(exports, "__esModule", {
- value: true
- });
- exports.default = void 0;
-
- var _lodash = _interopRequireDefault(require("lodash"));
-
- var _iterateJsdoc = _interopRequireDefault(require("../iterateJsdoc"));
-
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
- const rootNamer = (desiredRoots, currentIndex) => {
- let name;
- let idx = currentIndex;
- const incremented = desiredRoots.length <= 1;
-
- if (incremented) {
- const base = desiredRoots[0];
- const suffix = idx++;
- name = `${base}${suffix}`;
- } else {
- name = desiredRoots.shift();
- }
-
- return [name, incremented, () => {
- return rootNamer(desiredRoots, idx);
- }];
- };
-
- var _default = (0, _iterateJsdoc.default)(({
- jsdoc,
- utils,
- context
- }) => {
- const preferredTagName = utils.getPreferredTagName({
- tagName: 'param'
- });
-
- if (!preferredTagName) {
- return;
- }
-
- const jsdocParameterNames = utils.getJsdocTagsDeep(preferredTagName);
- const shallowJsdocParameterNames = jsdocParameterNames.filter(tag => {
- return !tag.name.includes('.');
- }).map((tag, idx) => {
- return { ...tag,
- idx
- };
- });
-
- if (utils.avoidDocs()) {
- return;
- } // Param type is specified by type in @type
-
-
- if (utils.hasTag('type')) {
- return;
- }
-
- const {
- autoIncrementBase = 0,
- checkRestProperty = false,
- checkDestructured = true,
- checkDestructuredRoots = true,
- checkTypesPattern = '/^(?:[oO]bject|[aA]rray|PlainObject|Generic(?:Object|Array))$/',
- enableFixer = true,
- enableRootFixer = true,
- enableRestElementFixer = true,
- unnamedRootBase = ['root'],
- useDefaultObjectProperties = false
- } = context.options[0] || {};
- const checkTypesRegex = utils.getRegexFromString(checkTypesPattern);
- const missingTags = [];
- const functionParameterNames = utils.getFunctionParameterNames(useDefaultObjectProperties);
- const flattenedRoots = utils.flattenRoots(functionParameterNames).names;
- const paramIndex = {};
-
- const hasParamIndex = cur => {
- return _lodash.default.has(paramIndex, utils.dropPathSegmentQuotes(String(cur)));
- };
-
- const getParamIndex = cur => {
- return paramIndex[utils.dropPathSegmentQuotes(String(cur))];
- };
-
- const setParamIndex = (cur, idx) => {
- paramIndex[utils.dropPathSegmentQuotes(String(cur))] = idx;
- };
-
- flattenedRoots.forEach((cur, idx) => {
- setParamIndex(cur, idx);
- });
-
- const findExpectedIndex = (jsdocTags, indexAtFunctionParams) => {
- const remainingRoots = functionParameterNames.slice(indexAtFunctionParams || 0);
- const foundIndex = jsdocTags.findIndex(({
- name,
- newAdd
- }) => {
- return !newAdd && remainingRoots.some(remainingRoot => {
- if (Array.isArray(remainingRoot)) {
- return remainingRoot[1].names.includes(name);
- }
-
- if (typeof remainingRoot === 'object') {
- return name === remainingRoot.name;
- }
-
- return name === remainingRoot;
- });
- });
- const tags = foundIndex > -1 ? jsdocTags.slice(0, foundIndex) : jsdocTags.filter(({
- tag
- }) => {
- return tag === preferredTagName;
- });
- let tagLineCount = 0;
- tags.forEach(({
- source
- }) => {
- source.forEach(({
- tokens: {
- end
- }
- }) => {
- if (!end) {
- tagLineCount++;
- }
- });
- });
- return tagLineCount;
- };
-
- let [nextRootName, incremented, namer] = rootNamer([...unnamedRootBase], autoIncrementBase);
- functionParameterNames.forEach((functionParameterName, functionParameterIdx) => {
- let inc;
-
- if (Array.isArray(functionParameterName)) {
- const matchedJsdoc = shallowJsdocParameterNames[functionParameterIdx] || jsdocParameterNames[functionParameterIdx];
- let rootName;
-
- if (functionParameterName[0]) {
- rootName = functionParameterName[0];
- } else if (matchedJsdoc && matchedJsdoc.name) {
- rootName = matchedJsdoc.name;
-
- if (matchedJsdoc.type && matchedJsdoc.type.search(checkTypesRegex) === -1) {
- return;
- }
- } else {
- rootName = nextRootName;
- inc = incremented;
- [nextRootName, incremented, namer] = namer();
- }
-
- const {
- hasRestElement,
- hasPropertyRest,
- rests,
- names
- } = functionParameterName[1];
- const notCheckingNames = [];
-
- if (!enableRestElementFixer && hasRestElement) {
- return;
- }
-
- if (!checkDestructuredRoots) {
- return;
- }
-
- names.forEach((paramName, idx) => {
- // Add root if the root name is not in the docs (and is not already
- // in the tags to be fixed)
- if (!jsdocParameterNames.find(({
- name
- }) => {
- return name === rootName;
- }) && !missingTags.find(({
- functionParameterName: fpn
- }) => {
- return fpn === rootName;
- })) {
- const emptyParamIdx = jsdocParameterNames.findIndex(({
- name
- }) => {
- return !name;
- });
-
- if (emptyParamIdx > -1) {
- missingTags.push({
- functionParameterIdx: emptyParamIdx,
- functionParameterName: rootName,
- inc,
- remove: true
- });
- } else {
- missingTags.push({
- functionParameterIdx: hasParamIndex(rootName) ? getParamIndex(rootName) : getParamIndex(paramName),
- functionParameterName: rootName,
- inc
- });
- }
- }
-
- if (!checkDestructured) {
- return;
- }
-
- if (!checkRestProperty && rests[idx]) {
- return;
- }
-
- const fullParamName = `${rootName}.${paramName}`;
- const notCheckingName = jsdocParameterNames.find(({
- name,
- type: paramType
- }) => {
- return utils.comparePaths(name)(fullParamName) && paramType.search(checkTypesRegex) === -1 && paramType !== '';
- });
-
- if (notCheckingName !== undefined) {
- notCheckingNames.push(notCheckingName.name);
- }
-
- if (notCheckingNames.find(name => {
- return fullParamName.startsWith(name);
- })) {
- return;
- }
-
- if (jsdocParameterNames && !jsdocParameterNames.find(({
- name
- }) => {
- return utils.comparePaths(name)(fullParamName);
- })) {
- missingTags.push({
- functionParameterIdx: getParamIndex(functionParameterName[0] ? fullParamName : paramName),
- functionParameterName: fullParamName,
- inc,
- type: hasRestElement && !hasPropertyRest ? '{...any}' : undefined
- });
- }
- });
- return;
- }
-
- let funcParamName;
- let type;
-
- if (typeof functionParameterName === 'object') {
- if (!enableRestElementFixer && functionParameterName.restElement) {
- return;
- }
-
- funcParamName = functionParameterName.name;
- type = '{...any}';
- } else {
- funcParamName = functionParameterName;
- }
-
- if (jsdocParameterNames && !jsdocParameterNames.find(({
- name
- }) => {
- return name === funcParamName;
- })) {
- missingTags.push({
- functionParameterIdx: getParamIndex(funcParamName),
- functionParameterName: funcParamName,
- inc,
- type
- });
- }
- });
-
- const fix = ({
- functionParameterIdx,
- functionParameterName,
- remove,
- inc,
- type
- }) => {
- if (inc && !enableRootFixer) {
- return;
- }
-
- const createTokens = (tagIndex, sourceIndex, spliceCount) => {
- // console.log(sourceIndex, tagIndex, jsdoc.tags, jsdoc.source);
- const tokens = {
- number: sourceIndex + 1,
- tokens: {
- delimiter: '*',
- description: '',
- end: '',
- lineEnd: '',
- name: functionParameterName,
- newAdd: true,
- postDelimiter: ' ',
- postName: '',
- postTag: ' ',
- postType: type ? ' ' : '',
- start: jsdoc.source[sourceIndex].tokens.start,
- tag: `@${preferredTagName}`,
- type: type !== null && type !== void 0 ? type : ''
- }
- };
- jsdoc.tags.splice(tagIndex, spliceCount, {
- name: functionParameterName,
- newAdd: true,
- source: [tokens],
- tag: preferredTagName,
- type: type !== null && type !== void 0 ? type : ''
- });
- const firstNumber = jsdoc.source[0].number;
- jsdoc.source.splice(sourceIndex, spliceCount, tokens);
- jsdoc.source.slice(sourceIndex).forEach((src, idx) => {
- src.number = firstNumber + sourceIndex + idx;
- });
- };
-
- const offset = jsdoc.source.findIndex(({
- tokens: {
- tag,
- end
- }
- }) => {
- return tag || end;
- });
-
- if (remove) {
- createTokens(functionParameterIdx, offset + functionParameterIdx, 1);
- } else {
- const expectedIdx = findExpectedIndex(jsdoc.tags, functionParameterIdx);
- createTokens(expectedIdx, offset + expectedIdx, 0);
- }
- };
-
- const fixer = () => {
- missingTags.forEach(missingTag => {
- fix(missingTag);
- });
- };
-
- if (missingTags.length && jsdoc.source.length === 1) {
- utils.makeMultiline();
- }
-
- missingTags.forEach(({
- functionParameterName
- }) => {
- utils.reportJSDoc(`Missing JSDoc @${preferredTagName} "${functionParameterName}" declaration.`, null, enableFixer ? fixer : null);
- });
- }, {
- contextDefaults: true,
- meta: {
- docs: {
- description: 'Requires that all function parameters are documented.',
- url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-param'
- },
- fixable: 'code',
- schema: [{
- additionalProperties: false,
- properties: {
- autoIncrementBase: {
- default: 0,
- type: 'integer'
- },
- checkConstructors: {
- default: true,
- type: 'boolean'
- },
- checkDestructured: {
- default: true,
- type: 'boolean'
- },
- checkDestructuredRoots: {
- default: true,
- type: 'boolean'
- },
- checkGetters: {
- default: false,
- type: 'boolean'
- },
- checkRestProperty: {
- default: false,
- type: 'boolean'
- },
- checkSetters: {
- default: false,
- type: 'boolean'
- },
- checkTypesPattern: {
- type: 'string'
- },
- contexts: {
- items: {
- anyOf: [{
- type: 'string'
- }, {
- additionalProperties: false,
- properties: {
- comment: {
- type: 'string'
- },
- context: {
- type: 'string'
- }
- },
- type: 'object'
- }]
- },
- type: 'array'
- },
- enableFixer: {
- type: 'boolean'
- },
- enableRestElementFixer: {
- type: 'boolean'
- },
- enableRootFixer: {
- type: 'boolean'
- },
- exemptedBy: {
- items: {
- type: 'string'
- },
- type: 'array'
- },
- unnamedRootBase: {
- items: {
- type: 'string'
- },
- type: 'array'
- },
- useDefaultObjectProperties: {
- type: 'boolean'
- }
- },
- type: 'object'
- }],
- type: 'suggestion'
- }
- });
-
- exports.default = _default;
- module.exports = exports.default;
- //# sourceMappingURL=requireParam.js.map
|