Skip to content

Commit

Permalink
Add a warning about JSDoc annotation on return
Browse files Browse the repository at this point in the history
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=236169101
  • Loading branch information
rslawik authored and brad4d committed Mar 1, 2019
1 parent 70946b9 commit 1a1ff15
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 0 deletions.
16 changes: 16 additions & 0 deletions src/com/google/javascript/jscomp/CheckJSDoc.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ final class CheckJSDoc extends AbstractPostOrderCallback implements HotSwapCompi
"JSC_JSDOC_IN_BLOCK_COMMENT",
"Non-JSDoc comment has annotations. Did you mean to start it with '/**'?");

public static final DiagnosticType JSDOC_ON_RETURN =
DiagnosticType.warning(
"JSC_JSDOC_ON_RETURN", "JSDoc annotations are not supported on return.");

private static final Pattern COMMENT_PATTERN =
Pattern.compile("(/|(\n[ \t]*))\\*[ \t]*@[a-zA-Z]+[ \t\n{]");

Expand Down Expand Up @@ -156,6 +160,7 @@ public void visit(NodeTraversal t, Node n, Node parent) {
validateSuppress(n, info);
validateImplicitCast(n, info);
validateClosurePrimitive(n, info);
validateReturnJsDoc(n, info);
}

private void validateSuppress(Node n, JSDocInfo info) {
Expand Down Expand Up @@ -693,4 +698,15 @@ private void validateClosurePrimitive(Node n, JSDocInfo info) {
report(n, MISPLACED_ANNOTATION, "closurePrimitive", "must be on a function node");
}
}

/** Checks that there are no annotations on return. */
private void validateReturnJsDoc(Node n, JSDocInfo info) {
if (!n.isReturn() || info == null) {
return;
}
// @type is handled in validateTypeAnnotations method.
if (info.containsDeclaration() && !info.hasType()) {
report(n, JSDOC_ON_RETURN);
}
}
}
29 changes: 29 additions & 0 deletions test/com/google/javascript/jscomp/CheckJsDocTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import static com.google.javascript.jscomp.CheckJSDoc.INVALID_MODIFIES_ANNOTATION;
import static com.google.javascript.jscomp.CheckJSDoc.INVALID_NO_SIDE_EFFECT_ANNOTATION;
import static com.google.javascript.jscomp.CheckJSDoc.JSDOC_IN_BLOCK_COMMENT;
import static com.google.javascript.jscomp.CheckJSDoc.JSDOC_ON_RETURN;
import static com.google.javascript.jscomp.CheckJSDoc.MISPLACED_ANNOTATION;
import static com.google.javascript.jscomp.CheckJSDoc.MISPLACED_MSG_ANNOTATION;
import static com.google.javascript.jscomp.CheckJSDoc.MISPLACED_SUPPRESS;
Expand Down Expand Up @@ -1015,4 +1016,32 @@ public void testClosurePrimitive() {
testSame("/** @closurePrimitive {asserts.fail} */ let fail = function() {}");
testWarning("/** @fileoverview @closurePrimitive {asserts.fail} */", MISPLACED_ANNOTATION);
}

@Test
public void testJsDocOnReturn() {
// JSDoc on a class defined in return statement is a warning.
testWarning(
lines(
"/** @return {function(new:EventTarget)} */",
"function get() {",
"/** @implements {EventTarget} */",
"return class {};",
"}"),
JSDOC_ON_RETURN);
testWarning("function get() {\n/** @enum {string} */\nreturn {A: 'a'};\n}", JSDOC_ON_RETURN);
testWarning("function get() {\n/** @typedef {string} */\nreturn 'a';\n}", JSDOC_ON_RETURN);

// No warning when returning a class annotated with JSDoc.
testSame(
lines(
"/** @return {function(new:EventTarget)} */",
"function mixin() {",
"/** @implements {EventTarget} */",
"class MyEventTarget {}",
"return MyEventTarget;",
"}"));

// No warning for regular JSDoc.
testSame(lines("function f() {", "/** Some value. */", "return 5;", "}"));
}
}

0 comments on commit 1a1ff15

Please sign in to comment.