Skip to content

Commit

Permalink
Fix: Expected order of jsdoc tags (fixes #9412) (#9451)
Browse files Browse the repository at this point in the history
* Chore: Add tests to validate the jsdoc tag order (refs #9412)

* Fix: Expected order of jsdoc tags (fixes #9412)

* Chore: Improve code readability (refs #9412)

Create spelling variable names and remove unecessary if statement.
  • Loading branch information
Orlandster authored and kaicataldo committed Oct 22, 2017
1 parent f054ab5 commit b12cff8
Show file tree
Hide file tree
Showing 2 changed files with 467 additions and 33 deletions.
72 changes: 39 additions & 33 deletions lib/rules/valid-jsdoc.js
Expand Up @@ -226,8 +226,10 @@ module.exports = {
function checkJSDoc(node) {
const jsdocNode = sourceCode.getJSDocComment(node),
functionData = fns.pop(),
params = Object.create(null);
params = Object.create(null),
paramsTags = [];
let hasReturns = false,
returnsTag,
hasConstructor = false,
isInterface = false,
isOverride = false,
Expand Down Expand Up @@ -261,43 +263,13 @@ module.exports = {
case "param":
case "arg":
case "argument":
if (!tag.type) {
context.report({ node: jsdocNode, message: "Missing JSDoc parameter type for '{{name}}'.", data: { name: tag.name } });
}

if (!tag.description && requireParamDescription) {
context.report({ node: jsdocNode, message: "Missing JSDoc parameter description for '{{name}}'.", data: { name: tag.name } });
}

if (params[tag.name]) {
context.report({ node: jsdocNode, message: "Duplicate JSDoc parameter '{{name}}'.", data: { name: tag.name } });
} else if (tag.name.indexOf(".") === -1) {
params[tag.name] = 1;
}
paramsTags.push(tag);
break;

case "return":
case "returns":
hasReturns = true;

if (!requireReturn && !functionData.returnPresent && (tag.type === null || !isValidReturnType(tag)) && !isAbstract) {
context.report({
node: jsdocNode,
message: "Unexpected @{{title}} tag; function has no return statement.",
data: {
title: tag.title
}
});
} else {
if (requireReturnType && !tag.type) {
context.report({ node: jsdocNode, message: "Missing JSDoc return type." });
}

if (!isValidReturnType(tag) && !tag.description && requireReturnDescription) {
context.report({ node: jsdocNode, message: "Missing JSDoc return description." });
}
}

returnsTag = tag;
break;

case "constructor":
Expand Down Expand Up @@ -333,6 +305,40 @@ module.exports = {
}
});

paramsTags.forEach(param => {
if (!param.type) {
context.report({ node: jsdocNode, message: "Missing JSDoc parameter type for '{{name}}'.", data: { name: param.name } });
}
if (!param.description && requireParamDescription) {
context.report({ node: jsdocNode, message: "Missing JSDoc parameter description for '{{name}}'.", data: { name: param.name } });
}
if (params[param.name]) {
context.report({ node: jsdocNode, message: "Duplicate JSDoc parameter '{{name}}'.", data: { name: param.name } });
} else if (param.name.indexOf(".") === -1) {
params[param.name] = 1;
}
});

if (hasReturns) {
if (!requireReturn && !functionData.returnPresent && (returnsTag.type === null || !isValidReturnType(returnsTag)) && !isAbstract) {
context.report({
node: jsdocNode,
message: "Unexpected @{{title}} tag; function has no return statement.",
data: {
title: returnsTag.title
}
});
} else {
if (requireReturnType && !returnsTag.type) {
context.report({ node: jsdocNode, message: "Missing JSDoc return type." });
}

if (!isValidReturnType(returnsTag) && !returnsTag.description && requireReturnDescription) {
context.report({ node: jsdocNode, message: "Missing JSDoc return description." });
}
}
}

// check for functions missing @returns
if (!isOverride && !hasReturns && !hasConstructor && !isInterface &&
node.parent.kind !== "get" && node.parent.kind !== "constructor" &&
Expand Down

0 comments on commit b12cff8

Please sign in to comment.