Program: 27681
Project: 27681
Buggy source:
private JSType simpleInferExprType(Node n){
switch (n.getType()) {
case Token.REGEXP:
    return getRegexpType();
case Token.ARRAYLIT:
{
    if (!n.hasChildren()) {
      return null;
    }
    Node child=n.getFirstChild();
    JSType arrayType=simpleInferExprType(child);
    if (arrayType == null) {
      return null;
    }
    while (null != (child=child.getNext())) {
      if (!arrayType.equals(simpleInferExprType(child))) {
        return null;
      }
    }
    return getArrayType(arrayType);
  }
case Token.TRUE:
return JSType.TRUE_TYPE;
case Token.FALSE:
return JSType.FALSE_TYPE;
case Token.NAME:
{
String varName=n.getString();
if (varName.equals("String_Node_Str")) {
return JSType.UNDEFINED;
}
 else if (currentScope.isNamespaceLiteral(varName)) {
return null;
}
return currentScope.getDeclaredTypeOf(varName);
}
case Token.OBJECTLIT:
{
JSType objLitType=JSType.TOP_OBJECT;
for (Node prop : n.children()) {
JSType propType=simpleInferExprType(prop.getFirstChild());
if (propType == null) {
return null;
}
objLitType=objLitType.withProperty(new QualifiedName(NodeUtil.getObjectLitKeyName(prop)),propType);
}
return objLitType;
}
case Token.GETPROP:
JSType recvType=simpleInferExprType(n.getFirstChild());
if (recvType == null) {
return null;
}
QualifiedName qname=new QualifiedName(n.getLastChild().getString());
if (!recvType.mayHaveProp(qname)) {
return null;
}
return recvType.getProp(qname);
case Token.COMMA:
case Token.ASSIGN:
return simpleInferExprType(n.getLastChild());
case Token.CALL:
case Token.NEW:
JSType ratorType=simpleInferExprType(n.getFirstChild());
if (ratorType == null) {
return null;
}
FunctionType funType=ratorType.getFunType();
if (funType == null) {
return null;
}
if (funType.isGeneric()) {
ImmutableList.Builder<JSType> argTypes=ImmutableList.builder();
for (Node argNode=n.getFirstChild().getNext(); argNode != null; argNode=argNode.getNext()) {
JSType t=simpleInferExprType(argNode);
if (t == null) {
return null;
}
argTypes.add(t);
}
funType=funType.instantiateGenericsFromArgumentList(argTypes.build());
if (funType == null) {
return null;
}
}
return funType.getReturnType();
default :
switch (NodeUtil.getKnownValueType(n)) {
case NULL:
return JSType.NULL;
case VOID:
return JSType.UNDEFINED;
case NUMBER:
return JSType.NUMBER;
case STRING:
return JSType.STRING;
case BOOLEAN:
return JSType.BOOLEAN;
case UNDETERMINED:
default :
return null;
}
}
}

Fixed version (ground truth):
private JSType simpleInferExprType(Node n){
switch (n.getType()) {
case Token.REGEXP:
    return getRegexpType();
case Token.ARRAYLIT:
{
    if (!n.hasChildren()) {
      return null;
    }
    Node child=n.getFirstChild();
    JSType arrayType=simpleInferExprType(child);
    if (arrayType == null) {
      return null;
    }
    while (null != (child=child.getNext())) {
      if (!arrayType.equals(simpleInferExprType(child))) {
        return null;
      }
    }
    return getArrayType(arrayType);
  }
case Token.TRUE:
return JSType.TRUE_TYPE;
case Token.FALSE:
return JSType.FALSE_TYPE;
case Token.NAME:
{
String varName=n.getString();
if (varName.equals("String_Node_Str")) {
return JSType.UNDEFINED;
}
 else if (currentScope.isNamespaceLiteral(varName)) {
return null;
}
return currentScope.getDeclaredTypeOf(varName);
}
case Token.OBJECTLIT:
{
JSType objLitType=JSType.TOP_OBJECT;
for (Node prop : n.children()) {
JSType propType=simpleInferExprType(prop.getFirstChild());
if (propType == null) {
return null;
}
objLitType=objLitType.withProperty(new QualifiedName(NodeUtil.getObjectLitKeyName(prop)),propType);
}
return objLitType;
}
case Token.GETPROP:
JSType recvType=simpleInferExprType(n.getFirstChild());
if (recvType == null) {
return null;
}
QualifiedName qname=new QualifiedName(n.getLastChild().getString());
if (!recvType.mayHaveProp(qname)) {
return null;
}
return recvType.getProp(qname);
case Token.COMMA:
case Token.ASSIGN:
return simpleInferExprType(n.getLastChild());
case Token.CALL:
case Token.NEW:
JSType ratorType=simpleInferExprType(n.getFirstChild());
if (ratorType == null) {
return null;
}
FunctionType funType=ratorType.getFunType();
if (funType == null) {
return null;
}
if (funType.isGeneric()) {
ImmutableList.Builder<JSType> argTypes=ImmutableList.builder();
for (Node argNode=n.getFirstChild().getNext(); argNode != null; argNode=argNode.getNext()) {
JSType t=simpleInferExprType(argNode);
if (t == null) {
return null;
}
argTypes.add(t);
}
funType=funType.instantiateGenericsFromArgumentTypes(argTypes.build());
if (funType == null) {
return null;
}
}
return funType.getReturnType();
default :
switch (NodeUtil.getKnownValueType(n)) {
case NULL:
return JSType.NULL;
case VOID:
return JSType.UNDEFINED;
case NUMBER:
return JSType.NUMBER;
case STRING:
return JSType.STRING;
case BOOLEAN:
return JSType.BOOLEAN;
case UNDETERMINED:
default :
return null;
}
}
}