Program: 27091
Project: 27091
Buggy source:
/** 
 * Given a constructor type and a property name, check that the property has the JSDoc annotation @override iff the property is declared on a superclass. Several checks regarding inheritance correctness are also performed.
 */
private void checkDeclaredPropertyInheritance(NodeTraversal t,Node n,FunctionType ctorType,String propertyName,JSDocInfo info,JSType propertyType){
  if (hasUnknownOrEmptySupertype(ctorType)) {
    return;
  }
  FunctionType superClass=ctorType.getSuperClassConstructor();
  boolean superClassHasProperty=superClass != null && superClass.getInstanceType().hasProperty(propertyName);
  boolean superClassHasDeclaredProperty=superClass != null && superClass.getInstanceType().isPropertyTypeDeclared(propertyName);
  boolean superInterfaceHasProperty=false;
  boolean superInterfaceHasDeclaredProperty=false;
  if (ctorType.isInterface()) {
    for (    ObjectType interfaceType : ctorType.getExtendedInterfaces()) {
      superInterfaceHasProperty=superInterfaceHasProperty || interfaceType.hasProperty(propertyName);
      superInterfaceHasDeclaredProperty=superInterfaceHasDeclaredProperty || interfaceType.isPropertyTypeDeclared(propertyName);
    }
  }
  boolean declaredOverride=info != null && info.isOverride();
  boolean foundInterfaceProperty=false;
  if (ctorType.isConstructor()) {
    for (    JSType implementedInterface : ctorType.getAllImplementedInterfaces()) {
      if (implementedInterface.isUnknownType() || implementedInterface.isEmptyType()) {
        continue;
      }
      FunctionType interfaceType=implementedInterface.toObjectType().getConstructor();
      checkNotNull(interfaceType);
      boolean interfaceHasProperty=interfaceType.getPrototype().hasProperty(propertyName);
      foundInterfaceProperty=foundInterfaceProperty || interfaceHasProperty;
      if (!declaredOverride && interfaceHasProperty && !"String_Node_Str".equals(propertyName)) {
        compiler.report(t.makeError(n,HIDDEN_INTERFACE_PROPERTY,propertyName,interfaceType.getTopMostDefiningType(propertyName).toString()));
      }
    }
  }
  if (!declaredOverride && !superClassHasProperty && !superInterfaceHasProperty) {
    return;
  }
  ObjectType topInstanceType=superClassHasDeclaredProperty ? superClass.getTopMostDefiningType(propertyName) : null;
  boolean declaredLocally=ctorType.isConstructor() && (ctorType.getPrototype().hasOwnProperty(propertyName) || ctorType.getInstanceType().hasOwnProperty(propertyName));
  if (!declaredOverride && superClassHasDeclaredProperty && declaredLocally&& !"String_Node_Str".equals(propertyName)) {
    compiler.report(t.makeError(n,HIDDEN_SUPERCLASS_PROPERTY,propertyName,topInstanceType.toString()));
  }
  if (superClassHasDeclaredProperty) {
    JSType superClassPropType=superClass.getInstanceType().getPropertyType(propertyName);
    TemplateTypeMap ctorTypeMap=ctorType.getTypeOfThis().getTemplateTypeMap();
    if (!ctorTypeMap.isEmpty()) {
      superClassPropType=superClassPropType.visit(new TemplateTypeMapReplacer(typeRegistry,ctorTypeMap));
    }
    if (!propertyType.isSubtype(superClassPropType,this.subtypingMode)) {
      compiler.report(t.makeError(n,HIDDEN_SUPERCLASS_PROPERTY_MISMATCH,propertyName,topInstanceType.toString(),superClassPropType.toString(),propertyType.toString()));
    }
  }
 else   if (superInterfaceHasDeclaredProperty) {
    for (    ObjectType interfaceType : ctorType.getExtendedInterfaces()) {
      if (interfaceType.hasProperty(propertyName)) {
        JSType superPropertyType=interfaceType.getPropertyType(propertyName);
        if (!propertyType.isSubtype(superPropertyType,this.subtypingMode)) {
          topInstanceType=interfaceType.getConstructor().getTopMostDefiningType(propertyName);
          compiler.report(t.makeError(n,HIDDEN_SUPERCLASS_PROPERTY_MISMATCH,propertyName,topInstanceType.toString(),superPropertyType.toString(),propertyType.toString()));
        }
      }
    }
  }
 else   if (!foundInterfaceProperty && !superClassHasProperty && !superInterfaceHasProperty) {
    compiler.report(t.makeError(n,UNKNOWN_OVERRIDE,propertyName,ctorType.getInstanceType().toString()));
  }
}

Fixed version (ground truth):
/** 
 * Given a constructor type and a property name, check that the property has the JSDoc annotation @override iff the property is declared on a superclass. Several checks regarding inheritance correctness are also performed.
 */
private void checkDeclaredPropertyInheritance(NodeTraversal t,Node n,FunctionType ctorType,String propertyName,JSDocInfo info,JSType propertyType){
  if (hasUnknownOrEmptySupertype(ctorType)) {
    return;
  }
  FunctionType superClass=ctorType.getSuperClassConstructor();
  boolean superClassHasProperty=superClass != null && superClass.getInstanceType().hasProperty(propertyName);
  boolean superClassHasDeclaredProperty=superClass != null && superClass.getInstanceType().isPropertyTypeDeclared(propertyName);
  boolean superInterfaceHasProperty=false;
  boolean superInterfaceHasDeclaredProperty=false;
  if (ctorType.isInterface()) {
    for (    ObjectType interfaceType : ctorType.getExtendedInterfaces()) {
      superInterfaceHasProperty=superInterfaceHasProperty || interfaceType.hasProperty(propertyName);
      superInterfaceHasDeclaredProperty=superInterfaceHasDeclaredProperty || interfaceType.isPropertyTypeDeclared(propertyName);
    }
  }
  boolean declaredOverride=info != null && info.isOverride();
  boolean foundInterfaceProperty=false;
  if (ctorType.isConstructor()) {
    for (    JSType implementedInterface : ctorType.getAllImplementedInterfaces()) {
      if (implementedInterface.isUnknownType() || implementedInterface.isEmptyType()) {
        continue;
      }
      FunctionType interfaceType=implementedInterface.toObjectType().getConstructor();
      checkNotNull(interfaceType);
      boolean interfaceHasProperty=interfaceType.getPrototype().hasProperty(propertyName);
      foundInterfaceProperty=foundInterfaceProperty || interfaceHasProperty;
      if (!declaredOverride && interfaceHasProperty && !"String_Node_Str".equals(propertyName)&& !"String_Node_Str".equals(propertyName)) {
        compiler.report(t.makeError(n,HIDDEN_INTERFACE_PROPERTY,propertyName,interfaceType.getTopMostDefiningType(propertyName).toString()));
      }
    }
  }
  if (!declaredOverride && !superClassHasProperty && !superInterfaceHasProperty) {
    return;
  }
  ObjectType topInstanceType=superClassHasDeclaredProperty ? superClass.getTopMostDefiningType(propertyName) : null;
  boolean declaredLocally=ctorType.isConstructor() && (ctorType.getPrototype().hasOwnProperty(propertyName) || ctorType.getInstanceType().hasOwnProperty(propertyName));
  if (!declaredOverride && superClassHasDeclaredProperty && declaredLocally&& !"String_Node_Str".equals(propertyName)) {
    compiler.report(t.makeError(n,HIDDEN_SUPERCLASS_PROPERTY,propertyName,topInstanceType.toString()));
  }
  if (superClassHasDeclaredProperty) {
    JSType superClassPropType=superClass.getInstanceType().getPropertyType(propertyName);
    TemplateTypeMap ctorTypeMap=ctorType.getTypeOfThis().getTemplateTypeMap();
    if (!ctorTypeMap.isEmpty()) {
      superClassPropType=superClassPropType.visit(new TemplateTypeMapReplacer(typeRegistry,ctorTypeMap));
    }
    if (!propertyType.isSubtype(superClassPropType,this.subtypingMode)) {
      compiler.report(t.makeError(n,HIDDEN_SUPERCLASS_PROPERTY_MISMATCH,propertyName,topInstanceType.toString(),superClassPropType.toString(),propertyType.toString()));
    }
  }
 else   if (superInterfaceHasDeclaredProperty) {
    for (    ObjectType interfaceType : ctorType.getExtendedInterfaces()) {
      if (interfaceType.hasProperty(propertyName)) {
        JSType superPropertyType=interfaceType.getPropertyType(propertyName);
        if (!propertyType.isSubtype(superPropertyType,this.subtypingMode)) {
          topInstanceType=interfaceType.getConstructor().getTopMostDefiningType(propertyName);
          compiler.report(t.makeError(n,HIDDEN_SUPERCLASS_PROPERTY_MISMATCH,propertyName,topInstanceType.toString(),superPropertyType.toString(),propertyType.toString()));
        }
      }
    }
  }
 else   if (!foundInterfaceProperty && !superClassHasProperty && !superInterfaceHasProperty) {
    compiler.report(t.makeError(n,UNKNOWN_OVERRIDE,propertyName,ctorType.getInstanceType().toString()));
  }
}