typeParser.getFunctionType(fnDoc, declNode, ownerType, parentScope);
RawNominalType ctorType = null;
// Look at other annotations, eg, @constructor
if (fnDoc != null) {
NominalType parentClass = null;
if (fnDoc.hasBaseType()) {
if (!fnDoc.isConstructor()) {
warnings.add(JSError.make(
declNode, EXTENDS_NOT_ON_CTOR_OR_INTERF, functionName));
} else {
Node docNode = fnDoc.getBaseType().getRoot();
if (typeParser.hasKnownType(
docNode, ownerType, parentScope, typeParameters)) {
parentClass = typeParser.getNominalType(
docNode, ownerType, parentScope, typeParameters);
if (parentClass == null) {
warnings.add(JSError.make(
declNode, EXTENDS_NON_OBJECT, functionName,
docNode.toStringTree()));
} else if (parentClass.isInterface()) {
warnings.add(JSError.make(
declNode, TypeCheck.CONFLICTING_EXTENDED_TYPE,
"constructor", functionName));
parentClass = null;
}
}
}
}
ctorType =
declNode.isFunction() ? nominaltypesByNode.get(declNode) : null;
ImmutableSet<NominalType> implementedIntfs =
typeParser.getImplementedInterfaces(
fnDoc, ownerType, parentScope, typeParameters);
if (ctorType == null &&
(fnDoc.isConstructor() || fnDoc.isInterface())) {
// Anonymous type, don't register it.
return builder.buildDeclaration();
} else if (fnDoc.isConstructor()) {
String className = ctorType.toString();
if (parentClass == null && !"Object".equals(functionName)) {
parentClass = getObjectNominalType();
}
if (parentClass != null) {
if (!ctorType.addSuperClass(parentClass)) {
warnings.add(JSError.make(
declNode, INHERITANCE_CYCLE, className));
} else if (parentClass != getObjectNominalType()) {
if (ctorType.isStruct() && !parentClass.isStruct()) {
warnings.add(JSError.make(
declNode, TypeCheck.CONFLICTING_SHAPE_TYPE,
"struct", className));
} else if (ctorType.isDict() && !parentClass.isDict()) {
warnings.add(JSError.make(
declNode, TypeCheck.CONFLICTING_SHAPE_TYPE,
"dict", className));
}
}