private NominalType getMaybeParentClass(
     JSDocInfo jsdoc,
     String functionName,
     Node funNode,
     ImmutableList<String> typeParameters,
     DeclaredTypeRegistry registry) {
   if (!jsdoc.hasBaseType()) {
     return null;
   }
   if (!jsdoc.isConstructor()) {
     warnings.add(JSError.make(funNode, EXTENDS_NOT_ON_CTOR_OR_INTERF, functionName));
     return null;
   }
   Node docNode = jsdoc.getBaseType().getRoot();
   JSType extendedType = getMaybeTypeFromComment(docNode, registry, typeParameters);
   if (extendedType == null) {
     return null;
   }
   NominalType parentClass = extendedType.getNominalTypeIfSingletonObj();
   if (parentClass != null && parentClass.isClass()) {
     return parentClass;
   }
   if (parentClass == null) {
     warnings.add(
         JSError.make(funNode, EXTENDS_NON_OBJECT, functionName, extendedType.toString()));
   } else {
     Preconditions.checkState(parentClass.isInterface());
     warnings.add(JSError.make(funNode, CONFLICTING_EXTENDED_TYPE, "constructor", functionName));
   }
   return null;
 }
Пример #2
0
 boolean isNominalSubtypeOf(NominalType other) {
   RawNominalType thisRaw = this.rawType;
   if (thisRaw == other.rawType) {
     return areTypeMapsCompatible(other);
   }
   if (other.isBuiltinObject()) {
     return true;
   }
   if (other.isInterface()) {
     // If thisRaw is not finalized, thisRaw.interfaces may be null.
     for (NominalType i : thisRaw.getInterfaces()) {
       if (i.instantiateGenerics(this.typeMap).isNominalSubtypeOf(other)) {
         return true;
       }
     }
   }
   // Note that other can still be an interface here (implemented by a superclass)
   return isClass()
       && thisRaw.getSuperClass() != null
       && thisRaw.getSuperClass().instantiateGenerics(this.typeMap).isNominalSubtypeOf(other);
 }
Пример #3
0
 // Returns a type with the same raw type as other, but possibly different type maps.
 private NominalType findMatchingAncestorWith(NominalType other) {
   RawNominalType thisRaw = this.rawType;
   if (thisRaw == other.rawType) {
     return this;
   }
   if (other.isInterface()) {
     for (NominalType i : thisRaw.getInterfaces()) {
       NominalType nt = i.instantiateGenerics(this.typeMap).findMatchingAncestorWith(other);
       if (nt != null) {
         return nt;
       }
     }
   }
   // Note that other can still be an interface here (implemented by a superclass)
   if (isClass() && thisRaw.getSuperClass() != null) {
     return thisRaw
         .getSuperClass()
         .instantiateGenerics(this.typeMap)
         .findMatchingAncestorWith(other);
   }
   return null;
 }
 private ImmutableSet<NominalType> getInterfacesHelper(
     JSDocInfo jsdoc,
     DeclaredTypeRegistry registry,
     ImmutableList<String> typeParameters,
     boolean implementedIntfs) {
   ImmutableSet.Builder<NominalType> builder = ImmutableSet.builder();
   for (JSTypeExpression texp :
       (implementedIntfs ? jsdoc.getImplementedInterfaces() : jsdoc.getExtendedInterfaces())) {
     Node expRoot = texp.getRoot();
     JSType interfaceType = getMaybeTypeFromComment(expRoot, registry, typeParameters);
     if (interfaceType != null) {
       NominalType nt = interfaceType.getNominalTypeIfSingletonObj();
       if (nt != null && nt.isInterface()) {
         builder.add(nt);
       } else if (implementedIntfs) {
         warnings.add(JSError.make(expRoot, IMPLEMENTS_NON_INTERFACE, interfaceType.toString()));
       } else {
         warnings.add(JSError.make(expRoot, EXTENDS_NON_INTERFACE, interfaceType.toString()));
       }
     }
   }
   return builder.build();
 }