Skip to content

Commit 23f4cce

Browse files
committed
[NEW TYPE INFERENCE] Warn for anonymous nominal types.
Also fix some ported tests that use @typedef. ------------- Created by MOE: http://code.google.com/p/moe-java MOE_MIGRATED_REVID=66314920
1 parent f93bdc5 commit 23f4cce

File tree

4 files changed

+44
-12
lines changed

4 files changed

+44
-12
lines changed

src/com/google/javascript/jscomp/GlobalTypeInfo.java

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,13 @@ class GlobalTypeInfo implements CompilerPass {
149149
"A typedef variable represents a type name; " +
150150
"it cannot be assigned a value.");
151151

152+
static final DiagnosticType ANONYMOUS_NOMINAL_TYPE =
153+
DiagnosticType.warning(
154+
"JSC_ANONYMOUS_NOMINAL_TYPE",
155+
"Must specify a name when defining a class or interface.");
156+
152157
static final DiagnosticGroup ALL_DIAGNOSTICS = new DiagnosticGroup(
158+
ANONYMOUS_NOMINAL_TYPE,
153159
CANNOT_INIT_TYPEDEF,
154160
CANNOT_OVERRIDE_FINAL_METHOD,
155161
CONSTRUCTOR_REQUIRED,
@@ -227,11 +233,8 @@ String getFunInternalName(Node n) {
227233
Preconditions.checkArgument(n.isFunction());
228234
Node fnNameNode = NodeUtil.getFunctionNameNode(n);
229235
// We don't want to use qualified names here
230-
if (fnNameNode.isName()) {
231-
String s = fnNameNode.getString();
232-
if (s != null && !s.isEmpty()) {
233-
return s;
234-
}
236+
if (fnNameNode != null && fnNameNode.isName()) {
237+
return fnNameNode.getString();
235238
}
236239
return anonFunNames.get(n);
237240
}
@@ -547,6 +550,10 @@ private void initFnScope(Node fn, Scope parentScope) {
547550
}
548551
JSDocInfo fnDoc = NodeUtil.getFunctionJSDocInfo(fn);
549552
if (fnDoc != null && (fnDoc.isConstructor() || fnDoc.isInterface())) {
553+
if (qname == null) {
554+
warnings.add(JSError.make(fn, ANONYMOUS_NOMINAL_TYPE));
555+
return;
556+
}
550557
ImmutableList<String> typeParameters = fnDoc.getTemplateTypeNames();
551558
RawNominalType rawNominalType;
552559
if (fnDoc.isInterface()) {
@@ -1232,7 +1239,12 @@ private DeclaredFunctionType computeFnDeclaredType(
12321239
ImmutableSet<NominalType> implementedIntfs =
12331240
typeParser.getImplementedInterfaces(
12341241
fnDoc, ownerType, parentScope, typeParameters);
1235-
if (fnDoc.isConstructor()) {
1242+
1243+
if (ctorType == null &&
1244+
(fnDoc.isConstructor() || fnDoc.isInterface())) {
1245+
// Anonymous type, don't register it.
1246+
return builder.buildDeclaration();
1247+
} else if (fnDoc.isConstructor()) {
12361248
String className = ctorType.toString();
12371249
if (parentClass != null) {
12381250
if (!ctorType.addSuperClass(parentClass)) {

src/com/google/javascript/jscomp/NewTypeInference.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,6 @@
5757
*
5858
* Features left to implement:
5959
* - @enum
60-
* - @typedef
61-
* - @define
6260
* - @lends
6361
* - @private (maybe)
6462
* - @protected (maybe)
@@ -160,6 +158,11 @@ public class NewTypeInference implements CompilerPass {
160158
"JSC_CONST_REASSIGNED",
161159
"Cannot change the value of a constant.");
162160

161+
static final DiagnosticType NOT_A_CONSTRUCTOR =
162+
DiagnosticType.warning(
163+
"JSC_NOT_A_CONSTRUCTOR",
164+
"Expected a constructor but found type {0}.");
165+
163166
static final DiagnosticGroup ALL_DIAGNOSTICS = new DiagnosticGroup(
164167
CALL_FUNCTION_WITH_BOTTOM_FORMAL,
165168
CONST_REASSIGNED,
@@ -173,6 +176,7 @@ public class NewTypeInference implements CompilerPass {
173176
INVALID_OPERAND_TYPE,
174177
MISTYPED_ASSIGN_RHS,
175178
NON_NUMERIC_ARRAY_INDEX,
179+
NOT_A_CONSTRUCTOR,
176180
NOT_UNIQUE_INSTANTIATION,
177181
POSSIBLY_INEXISTENT_PROPERTY,
178182
PROPERTY_ACCESS_ON_NONOBJECT,
@@ -184,7 +188,6 @@ public class NewTypeInference implements CompilerPass {
184188
TypeCheck.ILLEGAL_PROPERTY_CREATION,
185189
TypeCheck.IN_USED_WITH_STRUCT,
186190
TypeCheck.INEXISTENT_PROPERTY,
187-
TypeCheck.NOT_A_CONSTRUCTOR,
188191
TypeCheck.NOT_CALLABLE,
189192
TypeCheck.WRONG_ARGUMENT_COUNT,
190193
TypeValidator.ILLEGAL_PROPERTY_ACCESS,
@@ -1380,7 +1383,7 @@ private EnvTypePair analyzeExprFwd(
13801383
return analyzeCallNodeArgumentsFwd(expr, inEnv);
13811384
} else if (expr.isNew() && !funType.isConstructor()) {
13821385
warnings.add(JSError.make(
1383-
expr, TypeCheck.NOT_A_CONSTRUCTOR, funType.toString()));
1386+
expr, NOT_A_CONSTRUCTOR, funType.toString()));
13841387
return analyzeCallNodeArgumentsFwd(expr, inEnv);
13851388
}
13861389
int maxArity = funType.getMaxArity();

src/com/google/javascript/jscomp/NodeUtil.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,9 @@ static Node getFunctionNameNode(Node n) {
439439

440440
default:
441441
// function name() ...
442-
return n.getFirstChild();
442+
Node funNameNode = n.getFirstChild();
443+
// Don't return the name node for anonymous functions
444+
return funNameNode.getString().isEmpty() ? null : funNameNode;
443445
}
444446
}
445447

test/com/google/javascript/jscomp/NewTypeInferenceTest.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1909,6 +1909,21 @@ public void testUnionOfFunctionAndNumber() {
19091909
TypeCheck.NOT_CALLABLE, NewTypeInference.INVALID_ARGUMENT_TYPE));
19101910
}
19111911

1912+
public void testAnonymousNominalType() {
1913+
typeCheck(
1914+
"function f() { return {}; }\n" +
1915+
"/** @constructor */\n" +
1916+
"f().Foo = function() {};",
1917+
GlobalTypeInfo.ANONYMOUS_NOMINAL_TYPE);
1918+
1919+
typeCheck(
1920+
"var x = {};\n" +
1921+
"function f() { return x; }\n" +
1922+
"/** @constructor */\n" +
1923+
"f().Foo = function() {};\n" +
1924+
"new (f().Foo)();",
1925+
GlobalTypeInfo.ANONYMOUS_NOMINAL_TYPE);
1926+
}
19121927

19131928
public void testFoo() {
19141929
typeCheck(
@@ -1917,7 +1932,7 @@ public void testFoo() {
19171932

19181933
typeCheck(
19191934
"function Foo() {}; new Foo();",
1920-
TypeCheck.NOT_A_CONSTRUCTOR);
1935+
NewTypeInference.NOT_A_CONSTRUCTOR);
19211936

19221937
checkNoWarnings(
19231938
"/** @constructor */ function Foo() {};\n" +

0 commit comments

Comments
 (0)