Skip to content

Commit

Permalink
Check @implements annotations on classes as well as @constructor-anno…
Browse files Browse the repository at this point in the history
…tated functions.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=138136196
  • Loading branch information
tbreisacher authored and blickly committed Nov 4, 2016
1 parent 65fe1f0 commit 0bc0330
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 5 deletions.
Expand Up @@ -578,18 +578,18 @@ private void maybeAddGoogScopeUsage(NodeTraversal t, Node n, Node parent) {
* <li><pre>var foo = function() {};</pre> * <li><pre>var foo = function() {};</pre>
* <li><pre>foo.bar = function() {};</pre> * <li><pre>foo.bar = function() {};</pre>
*/ */
private boolean declaresFunction(Node n) { private boolean declaresFunctionOrClass(Node n) {
if (n.isFunction()) { if (n.isFunction() || n.isClass()) {
return true; return true;
} }


if (n.isAssign() && n.getLastChild().isFunction()) { if (n.isAssign() && (n.getLastChild().isFunction() || n.getLastChild().isClass())) {
return true; return true;
} }


if (NodeUtil.isNameDeclaration(n) if (NodeUtil.isNameDeclaration(n)
&& n.getFirstChild().hasChildren() && n.getFirstChild().hasChildren()
&& n.getFirstFirstChild().isFunction()) { && (n.getFirstFirstChild().isFunction() || n.getFirstFirstChild().isClass())) {
return true; return true;
} }


Expand All @@ -602,7 +602,7 @@ private void maybeAddJsDocUsages(NodeTraversal t, Node n) {
return; return;
} }


if (declaresFunction(n)) { if (declaresFunctionOrClass(n)) {
for (JSTypeExpression expr : info.getImplementedInterfaces()) { for (JSTypeExpression expr : info.getImplementedInterfaces()) {
maybeAddUsage(t, n, expr); maybeAddUsage(t, n, expr);
} }
Expand Down
50 changes: 50 additions & 0 deletions test/com/google/javascript/jscomp/MissingRequireTest.java
Expand Up @@ -448,6 +448,56 @@ public void testFailWithImplements() {
testMissingRequire(js, warning); testMissingRequire(js, warning);
} }


public void testFailWithImplements_class() {
setAcceptedLanguage(LanguageMode.ECMASCRIPT_NEXT);

String[] js = new String[] {
"var goog = {};"
+ "goog.provide('example.Foo'); /** @interface */ example.Foo = function() {};",

"/** @implements {example.Foo} */ var SomeClass = class {};"
};
String warning = "missing require: 'example.Foo'";
testMissingRequire(js, warning);
}

public void testFailWithImplements_class2() {
setAcceptedLanguage(LanguageMode.ECMASCRIPT_NEXT);

String[] js = new String[] {
"var goog = {};"
+ "goog.provide('example.Foo'); /** @interface */ example.Foo = function() {};",

"goog.provide('example.Bar'); /** @implements {example.Foo} */ example.Bar = class {};"
};
String warning = "missing require: 'example.Foo'";
testMissingRequire(js, warning);
}

public void testFailWithImplements_googModule() {
String[] js = new String[] {
"goog.provide('example.Interface'); /** @interface */ example.Interface = function() {};",

"goog.module('foo.Bar');"
+ "/** @constructor @implements {example.Interface} */ function Bar() {}; exports = Bar;"
};
String warning = "missing require: 'example.Interface'";
testMissingRequire(js, warning);
}

public void testFailWithImplements_class_googModule() {
setAcceptedLanguage(LanguageMode.ECMASCRIPT_NEXT);

String[] js = new String[] {
"goog.provide('example.Interface'); /** @interface */ example.Interface = function() {};",

"goog.module('foo.Bar');"
+ "/** @implements {example.Interface} */ class Bar {}; exports = Bar;"
};
String warning = "missing require: 'example.Interface'";
testMissingRequire(js, warning);
}

public void testInterfaceExtends() { public void testInterfaceExtends() {
String js = String js =
LINE_JOINER.join( LINE_JOINER.join(
Expand Down

0 comments on commit 0bc0330

Please sign in to comment.