Program: 27694
Project: 27694
Buggy source:
private DeclaredFunctionType computeFnDeclaredType(JSDocInfo fnDoc,String functionName,Node declNode,RawNominalType ownerType,Scope parentScope){
  Preconditions.checkArgument(declNode.isFunction() || declNode.isGetProp());
  Node parent=declNode.getParent();
  if (fnDoc == null && !NodeUtil.functionHasInlineJsdocs(declNode) && parent.isCall() && declNode != parent.getFirstChild()) {
    FunctionType calleeDeclType=getDeclaredFunctionTypeOfCalleeIfAny(parent.getFirstChild(),parentScope);
    if (calleeDeclType != null) {
      int index=parent.getIndexOfChild(declNode) - 1;
      JSType declTypeFromCallee=calleeDeclType.getFormalType(index);
      if (declTypeFromCallee != null) {
        DeclaredFunctionType t=computeFnDeclaredTypeFromCallee(declNode,declTypeFromCallee);
        if (t != null) {
          return t;
        }
      }
    }
  }
  ImmutableList<String> typeParameters=fnDoc == null ? null : fnDoc.getTemplateTypeNames();
  FunctionTypeBuilder builder=typeParser.getFunctionType(fnDoc,declNode,ownerType,parentScope);
  RawNominalType ctorType=null;
  if (fnDoc != null) {
    NominalType parentClass="String_Node_Str".equals(functionName) ? null : getObjectNominalType();
    if (fnDoc.hasBaseType()) {
      if (!fnDoc.isConstructor()) {
        warnings.add(JSError.make(declNode,EXTENDS_NOT_ON_CTOR_OR_INTERF,functionName));
      }
 else {
        Node docNode=fnDoc.getBaseType().getRootNode();
        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,"String_Node_Str",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())) {
      return builder.buildDeclaration();
    }
 else     if (fnDoc.isConstructor()) {
      String className=ctorType.toString();
      if (parentClass != null) {
        if (!ctorType.addSuperClass(parentClass)) {
          warnings.add(JSError.make(declNode,INHERITANCE_CYCLE,className));
        }
 else         if (ctorType.isStruct() && !parentClass.isStruct()) {
          warnings.add(JSError.make(declNode,TypeCheck.CONFLICTING_SHAPE_TYPE,className,"String_Node_Str","String_Node_Str"));
        }
 else         if (ctorType.isDict() && !parentClass.isDict()) {
          warnings.add(JSError.make(declNode,TypeCheck.CONFLICTING_SHAPE_TYPE,className,"String_Node_Str","String_Node_Str"));
        }
      }
      if (ctorType.isDict() && !implementedIntfs.isEmpty()) {
        warnings.add(JSError.make(declNode,DICT_IMPLEMENTS_INTERF,className));
      }
      boolean noCycles=ctorType.addInterfaces(implementedIntfs);
      Preconditions.checkState(noCycles);
      builder.addNominalType(ctorType.getAsNominalType());
    }
 else     if (fnDoc.isInterface()) {
      if (declNode.isFunction() && !NodeUtil.isEmptyBlock(NodeUtil.getFunctionBody(declNode))) {
        warnings.add(JSError.make(declNode,INTERFACE_WITH_A_BODY));
      }
      if (!implementedIntfs.isEmpty()) {
        warnings.add(JSError.make(declNode,TypeCheck.CONFLICTING_IMPLEMENTED_TYPE,functionName));
      }
      boolean noCycles=ctorType.addInterfaces(typeParser.getExtendedInterfaces(fnDoc,ownerType,parentScope,typeParameters));
      if (!noCycles) {
        warnings.add(JSError.make(declNode,INHERITANCE_CYCLE,ctorType.toString()));
      }
      builder.addNominalType(ctorType.getAsNominalType());
    }
 else     if (!implementedIntfs.isEmpty()) {
      warnings.add(JSError.make(declNode,IMPLEMENTS_WITHOUT_CONSTRUCTOR,functionName));
    }
  }
  if (ownerType != null) {
    builder.addReceiverType(ownerType.getAsNominalType());
  }
  DeclaredFunctionType result=builder.buildDeclaration();
  if (ctorType != null) {
    ctorType.setCtorFunction(result.toFunctionType());
  }
  return result;
}

Fixed version (ground truth):
private DeclaredFunctionType computeFnDeclaredType(JSDocInfo fnDoc,String functionName,Node declNode,RawNominalType ownerType,Scope parentScope){
  Preconditions.checkArgument(declNode.isFunction() || declNode.isGetProp());
  Node parent=declNode.getParent();
  if (fnDoc == null && !NodeUtil.functionHasInlineJsdocs(declNode) && parent.isCall() && declNode != parent.getFirstChild()) {
    FunctionType calleeDeclType=getDeclaredFunctionTypeOfCalleeIfAny(parent.getFirstChild(),parentScope);
    if (calleeDeclType != null) {
      int index=parent.getIndexOfChild(declNode) - 1;
      JSType declTypeFromCallee=calleeDeclType.getFormalType(index);
      if (declTypeFromCallee != null) {
        DeclaredFunctionType t=computeFnDeclaredTypeFromCallee(declNode,declTypeFromCallee);
        if (t != null) {
          return t;
        }
      }
    }
  }
  ImmutableList<String> typeParameters=fnDoc == null ? null : fnDoc.getTemplateTypeNames();
  FunctionTypeBuilder builder=typeParser.getFunctionType(fnDoc,declNode,ownerType,parentScope);
  RawNominalType ctorType=null;
  if (fnDoc != null) {
    NominalType parentClass="String_Node_Str".equals(functionName) ? null : getObjectNominalType();
    if (fnDoc.hasBaseType()) {
      if (!fnDoc.isConstructor()) {
        warnings.add(JSError.make(declNode,EXTENDS_NOT_ON_CTOR_OR_INTERF,functionName));
      }
 else {
        Node docNode=fnDoc.getBaseType().getRootNode();
        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,"String_Node_Str",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())) {
      return builder.buildDeclaration();
    }
 else     if (fnDoc.isConstructor()) {
      String className=ctorType.toString();
      if (parentClass != null) {
        if (!ctorType.addSuperClass(parentClass)) {
          warnings.add(JSError.make(declNode,INHERITANCE_CYCLE,className));
        }
 else         if (ctorType.isStruct() && !parentClass.isStruct()) {
          warnings.add(JSError.make(declNode,TypeCheck.CONFLICTING_SHAPE_TYPE,"String_Node_Str",className));
        }
 else         if (ctorType.isDict() && !parentClass.isDict()) {
          warnings.add(JSError.make(declNode,TypeCheck.CONFLICTING_SHAPE_TYPE,"String_Node_Str",className));
        }
      }
      if (ctorType.isDict() && !implementedIntfs.isEmpty()) {
        warnings.add(JSError.make(declNode,DICT_IMPLEMENTS_INTERF,className));
      }
      boolean noCycles=ctorType.addInterfaces(implementedIntfs);
      Preconditions.checkState(noCycles);
      builder.addNominalType(ctorType.getAsNominalType());
    }
 else     if (fnDoc.isInterface()) {
      if (declNode.isFunction() && !NodeUtil.isEmptyBlock(NodeUtil.getFunctionBody(declNode))) {
        warnings.add(JSError.make(declNode,INTERFACE_WITH_A_BODY));
      }
      if (!implementedIntfs.isEmpty()) {
        warnings.add(JSError.make(declNode,TypeCheck.CONFLICTING_IMPLEMENTED_TYPE,functionName));
      }
      boolean noCycles=ctorType.addInterfaces(typeParser.getExtendedInterfaces(fnDoc,ownerType,parentScope,typeParameters));
      if (!noCycles) {
        warnings.add(JSError.make(declNode,INHERITANCE_CYCLE,ctorType.toString()));
      }
      builder.addNominalType(ctorType.getAsNominalType());
    }
 else     if (!implementedIntfs.isEmpty()) {
      warnings.add(JSError.make(declNode,IMPLEMENTS_WITHOUT_CONSTRUCTOR,functionName));
    }
  }
  if (ownerType != null) {
    builder.addReceiverType(ownerType.getAsNominalType());
  }
  DeclaredFunctionType result=builder.buildDeclaration();
  if (ctorType != null) {
    ctorType.setCtorFunction(result.toFunctionType());
  }
  return result;
}