Index: Source/devtools/scripts/jsdoc-validator/src/org/chromium/devtools/jsdoc/checks/MethodAnnotationChecker.java |
diff --git a/Source/devtools/scripts/jsdoc-validator/src/org/chromium/devtools/jsdoc/checks/ReturnAnnotationChecker.java b/Source/devtools/scripts/jsdoc-validator/src/org/chromium/devtools/jsdoc/checks/MethodAnnotationChecker.java |
similarity index 73% |
copy from Source/devtools/scripts/jsdoc-validator/src/org/chromium/devtools/jsdoc/checks/ReturnAnnotationChecker.java |
copy to Source/devtools/scripts/jsdoc-validator/src/org/chromium/devtools/jsdoc/checks/MethodAnnotationChecker.java |
index 60937784ebb6eff2f4a5ff87b27335331ecd83c2..4ec6b728b398d26a90c76d3e4adabf0d1719a3d7 100644 |
--- a/Source/devtools/scripts/jsdoc-validator/src/org/chromium/devtools/jsdoc/checks/ReturnAnnotationChecker.java |
+++ b/Source/devtools/scripts/jsdoc-validator/src/org/chromium/devtools/jsdoc/checks/MethodAnnotationChecker.java |
@@ -1,5 +1,6 @@ |
package org.chromium.devtools.jsdoc.checks; |
+import com.google.common.base.Joiner; |
import com.google.javascript.rhino.head.Token; |
import com.google.javascript.rhino.head.ast.AstNode; |
import com.google.javascript.rhino.head.ast.Comment; |
@@ -8,9 +9,15 @@ import com.google.javascript.rhino.head.ast.ObjectProperty; |
import com.google.javascript.rhino.head.ast.ReturnStatement; |
import java.util.HashSet; |
+import java.util.List; |
import java.util.Set; |
+import java.util.regex.Matcher; |
+import java.util.regex.Pattern; |
-public final class ReturnAnnotationChecker extends ContextTrackingChecker { |
+public final class MethodAnnotationChecker extends ContextTrackingChecker { |
+ |
+ private static final Pattern PARAM_PATTERN = |
+ Pattern.compile("@param\\s+\\{.+\\}\\s+([^\\s]+)(?:[^}]*)$", Pattern.MULTILINE); |
private final Set<FunctionRecord> valueReturningFunctions = new HashSet<>(); |
private final Set<FunctionRecord> throwingFunctions = new HashSet<>(); |
@@ -18,6 +25,9 @@ public final class ReturnAnnotationChecker extends ContextTrackingChecker { |
@Override |
public void enterNode(AstNode node) { |
switch (node.getType()) { |
+ case Token.FUNCTION: |
+ handleFunction((FunctionNode) node); |
+ break; |
case Token.RETURN: |
handleReturn((ReturnStatement) node); |
break; |
@@ -29,6 +39,41 @@ public final class ReturnAnnotationChecker extends ContextTrackingChecker { |
} |
} |
+ private void handleFunction(FunctionNode node) { |
+ int actualParamCount = node.getParams().size(); |
+ if (actualParamCount == 0) { |
+ return; |
+ } |
+ Comment jsDocNode = AstUtil.getJsDocNode(node); |
+ String[] nonAnnotatedParams = getNonAnnotatedParamData(node.getParams(), jsDocNode); |
+ if (nonAnnotatedParams.length > 0 && node.getParams().size() != nonAnnotatedParams.length) { |
+ reportErrorAtNodeStart(jsDocNode, String.format( |
+ "No @param JSDoc tag found for parameters: [%s]", |
+ Joiner.on(',').join(nonAnnotatedParams))); |
+ } |
+ } |
+ |
+ private String[] getNonAnnotatedParamData(List<AstNode> params, Comment jsDocNode) { |
+ if (jsDocNode == null) { |
+ return new String[0]; |
+ } |
+ Set<String> paramNames = new HashSet<>(); |
+ for (AstNode paramNode : params) { |
+ String paramName = getContext().getNodeText(paramNode); |
+ if (!paramNames.add(paramName)) { |
+ reportErrorAtNodeStart(paramNode, |
+ String.format("Duplicate function argument name: %s", paramName)); |
+ } |
+ } |
+ String jsDoc = getContext().getNodeText(jsDocNode); |
+ Matcher m = PARAM_PATTERN.matcher(jsDoc); |
+ while (m.find()) { |
+ String jsDocParam = m.group(1); |
+ paramNames.remove(jsDocParam); |
+ } |
+ return paramNames.toArray(new String[paramNames.size()]); |
+ } |
+ |
private void handleReturn(ReturnStatement node) { |
if (node.getReturnValue() == null || AstUtil.parentOfType(node, Token.ASSIGN) != null) { |
return; |