Skip to content

Commit 777ab36

Browse files
rishipalcopybara-github
authored andcommitted
Report lint finding for missing type annotations on override methods and fields.
PiperOrigin-RevId: 345088203
1 parent 8ec59c1 commit 777ab36

File tree

2 files changed

+87
-25
lines changed

2 files changed

+87
-25
lines changed

src/com/google/javascript/jscomp/lint/CheckJSDocStyle.java

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import com.google.javascript.jscomp.DiagnosticGroup;
2525
import com.google.javascript.jscomp.DiagnosticType;
2626
import com.google.javascript.jscomp.ExportTestFunctions;
27+
import com.google.javascript.jscomp.JSError;
2728
import com.google.javascript.jscomp.NodeTraversal;
2829
import com.google.javascript.jscomp.NodeTraversal.AbstractPostOrderCallback;
2930
import com.google.javascript.jscomp.NodeTraversal.AbstractPreOrderCallback;
@@ -55,7 +56,7 @@ public final class CheckJSDocStyle extends AbstractPostOrderCallback implements
5556
+ " instead?");
5657

5758
public static final DiagnosticType MISSING_PARAMETER_JSDOC =
58-
DiagnosticType.disabled("JSC_MISSING_PARAMETER_JSDOC", "Parameter must have JSDoc.");
59+
DiagnosticType.disabled("JSC_MISSING_PARAMETER_JSDOC", "Parameter must have JSDoc.{0}");
5960

6061
public static final DiagnosticType MIXED_PARAM_JSDOC_STYLES =
6162
DiagnosticType.disabled("JSC_MIXED_PARAM_JSDOC_STYLES",
@@ -64,7 +65,7 @@ public final class CheckJSDocStyle extends AbstractPostOrderCallback implements
6465
public static final DiagnosticType MISSING_RETURN_JSDOC =
6566
DiagnosticType.disabled(
6667
"JSC_MISSING_RETURN_JSDOC",
67-
"Function with non-trivial return must have JSDoc indicating the return type.");
68+
"Function with non-trivial return must have JSDoc indicating the return type.{0}");
6869

6970
public static final DiagnosticType MUST_BE_PRIVATE =
7071
DiagnosticType.disabled(
@@ -234,7 +235,7 @@ private void visitFunction(NodeTraversal t, Node function) {
234235
checkParams(t, function, jsDoc);
235236
}
236237
checkNoTypeOnGettersAndSetters(t, function, jsDoc);
237-
checkReturn(t, function, jsDoc);
238+
checkReturn(function, jsDoc);
238239
}
239240
}
240241

@@ -308,10 +309,6 @@ private boolean isConstructorWithoutParameters(Node function) {
308309
}
309310

310311
private void checkParams(NodeTraversal t, Node function, JSDocInfo jsDoc) {
311-
if (jsDoc != null && jsDoc.isOverride()) {
312-
return;
313-
}
314-
315312
if (jsDoc != null && jsDoc.getType() != null) {
316313
// Sometimes functions are declared with @type {function(Foo, Bar)} instead of
317314
// @param {Foo} foo
@@ -329,7 +326,17 @@ private void checkParams(NodeTraversal t, Node function, JSDocInfo jsDoc) {
329326
} else {
330327
Node paramList = NodeUtil.getFunctionParameters(function);
331328
if (!paramList.hasXChildren(paramsFromJsDoc.size())) {
332-
t.report(paramList, WRONG_NUMBER_OF_PARAMS);
329+
compiler.report(
330+
JSError.make(
331+
paramList,
332+
WRONG_NUMBER_OF_PARAMS,
333+
jsDoc.isOverride()
334+
?
335+
// moe:begin_strip
336+
" Please see go/tsjs-problematic-patterns for why @overrides require explicit"
337+
+ " @param types."
338+
// moe:end_strip_and_replace ""
339+
: ""));
333340
return;
334341
}
335342

@@ -429,12 +436,8 @@ private boolean hasAnyInlineJsDoc(Node function) {
429436
return false;
430437
}
431438

432-
private void checkReturn(NodeTraversal t, Node function, JSDocInfo jsDoc) {
433-
if (jsDoc != null
434-
&& (jsDoc.hasType()
435-
|| jsDoc.isConstructor()
436-
|| jsDoc.hasReturnType()
437-
|| jsDoc.isOverride())) {
439+
private void checkReturn(Node function, JSDocInfo jsDoc) {
440+
if (jsDoc != null && (jsDoc.hasType() || jsDoc.isConstructor() || jsDoc.hasReturnType())) {
438441
return;
439442
}
440443

@@ -450,7 +453,17 @@ private void checkReturn(NodeTraversal t, Node function, JSDocInfo jsDoc) {
450453
FindNonTrivialReturn finder = new FindNonTrivialReturn();
451454
NodeTraversal.traverse(compiler, function.getLastChild(), finder);
452455
if (finder.found) {
453-
t.report(function, MISSING_RETURN_JSDOC);
456+
compiler.report(
457+
JSError.make(
458+
function,
459+
MISSING_RETURN_JSDOC,
460+
jsDoc != null && jsDoc.isOverride()
461+
?
462+
// moe:begin_strip
463+
" Please see go/tsjs-problematic-patterns for why @overrides require explicit"
464+
+ " @return types.."
465+
// moe:end_strip_and_replace ""
466+
: ""));
454467
}
455468
}
456469

test/com/google/javascript/jscomp/lint/CheckJSDocStyleTest.java

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -448,10 +448,6 @@ public void testMissingParam_noWarning() {
448448
" */",
449449
"function f(x, y) {}"));
450450

451-
testSame(lines(
452-
"/** @override */",
453-
"Foo.bar = function(x, y) {}"));
454-
455451
testSame(lines(
456452
"/**",
457453
" * @param {string=} x",
@@ -1101,8 +1097,6 @@ public void testMissingReturn_functionStatement_noWarning() {
11011097
testSame("/** @param {number} x */ function f(x) { return; }");
11021098
testSame("/** @param {number} x\n * @return {number} */ function f(x) { return x; }");
11031099
testSame("/** @param {number} x */ function /** number */ f(x) { return x; }");
1104-
testSame("/** @inheritDoc */ function f(x) { return x; }");
1105-
testSame("/** @override */ function f(x) { return x; }");
11061100
}
11071101

11081102
@Test
@@ -1117,8 +1111,65 @@ public void testMissingReturn_assign_noWarning() {
11171111
testSame("/** @param {number} x */ f = function(x) { function bar() { return x; } }");
11181112
testSame("/** @param {number} x */ f = function(x) { return; }");
11191113
testSame("/** @param {number} x\n * @return {number} */ f = function(x) { return x; }");
1120-
testSame("/** @inheritDoc */ f = function(x) { return x; }");
1121-
testSame("/** @override */ f = function(x) { return x; }");
1114+
}
1115+
1116+
@Test
1117+
public void testMissingParamOrReturn_warnOnOverrideMethodsAndFields() {
1118+
testWarning(
1119+
lines(
1120+
"/** ",
1121+
" * @override ",
1122+
" * @param {string} x ",
1123+
" */",
1124+
" Foo.Bar = function(x) { return x; }"), // function assigned to a field
1125+
MISSING_RETURN_JSDOC);
1126+
testWarning(
1127+
lines(
1128+
"/** ",
1129+
" * @override ",
1130+
" * @param {string} x ",
1131+
" */",
1132+
" function f(x) { return x; }"),
1133+
MISSING_RETURN_JSDOC);
1134+
testWarning(
1135+
lines(
1136+
"/**",
1137+
" * @override",
1138+
" * @return {string}",
1139+
" */",
1140+
" Foo.Bar = function(x) { return x; }"),
1141+
MISSING_PARAMETER_JSDOC);
1142+
testWarning(
1143+
lines(
1144+
"/** ", " * @override ", " * @param {string} x ", " */", "Foo.bar = function(x, y) {}"),
1145+
WRONG_NUMBER_OF_PARAMS);
1146+
1147+
// also test `@inheritDoc` annotations
1148+
testWarning(
1149+
lines(
1150+
"/** ",
1151+
" * @inheritDoc ",
1152+
" * @return {string} x ",
1153+
" */",
1154+
"function f(x) { return x; }"),
1155+
MISSING_PARAMETER_JSDOC);
1156+
testWarning(
1157+
lines(
1158+
"/** ",
1159+
" * @inheritDoc ",
1160+
" * @return {string} x ",
1161+
" */",
1162+
"Foo.Bar = function(x) { return x; }"), // assigned to a field
1163+
MISSING_PARAMETER_JSDOC);
1164+
1165+
// inline param type
1166+
testNoWarning(
1167+
lines(
1168+
"/** ",
1169+
" * @override",
1170+
" * @return {string}",
1171+
" */",
1172+
"var f = function(/** string */ x) { return x; }"));
11221173
}
11231174

11241175
@Test
@@ -1129,8 +1180,6 @@ public void testMissingReturn_var_noWarning() {
11291180
testSame("/** @param {number} x */ var f = function(x) { return; }");
11301181
testSame("/** @param {number} x\n * @return {number} */ var f = function(x) { return x; }");
11311182
testSame("/** @const {function(number): number} */ var f = function(x) { return x; }");
1132-
testSame("/** @inheritDoc */ var f = function(x) { return x; }");
1133-
testSame("/** @override */ var f = function(x) { return x; }");
11341183
}
11351184

11361185
@Test

0 commit comments

Comments
 (0)