Program: 27609
Project: 27609
Buggy source:
/** 
 * Classes are processed in 3 phases: 1) The class name is extracted. 2) Class members are processed and rewritten. 3) The constructor is built.
 */
private void visitClass(Node classNode,Node parent){
  checkClassReassignment(classNode);
  Node className=classNode.getFirstChild();
  Node superClassName=className.getNext();
  Node classMembers=classNode.getLastChild();
  Node insertionPoint;
  if (!superClassName.isEmpty() && !superClassName.isQualifiedName()) {
    compiler.report(JSError.make(superClassName,DYNAMIC_EXTENDS_TYPE));
    return;
  }
  String fullClassName=null;
  boolean anonymous;
  if (NodeUtil.isStatement(classNode)) {
    fullClassName=className.getString();
    anonymous=false;
    insertionPoint=classNode;
  }
 else   if (parent.isAssign() && parent.getParent().isExprResult()) {
    fullClassName=parent.getFirstChild().getQualifiedName();
    if (fullClassName == null) {
      cannotConvert(parent,"String_Node_Str" + "String_Node_Str");
      return;
    }
    anonymous=true;
    insertionPoint=parent.getParent();
  }
 else   if (parent.isName()) {
    fullClassName=parent.getString();
    anonymous=true;
    insertionPoint=parent.getParent();
  }
 else {
    cannotConvert(parent,"String_Node_Str" + "String_Node_Str");
    return;
  }
  if (!className.isEmpty() && !className.getString().equals(fullClassName)) {
    cannotConvertYet(classNode,"String_Node_Str");
    return;
  }
  boolean useUnique=NodeUtil.isStatement(classNode) && !NodeUtil.isInFunction(classNode);
  String uniqueFullClassName=useUnique ? getUniqueClassName(fullClassName) : fullClassName;
  String superClassString=superClassName.getQualifiedName();
  Verify.verify(NodeUtil.isStatement(insertionPoint));
  Node constructor=null;
  JSDocInfo ctorJSDocInfo=null;
  for (  Node member : classMembers.children()) {
    if (member.isEmpty()) {
      continue;
    }
    if (member.isMemberDef() && member.getString().equals("String_Node_Str")) {
      ctorJSDocInfo=member.getJSDocInfo();
      constructor=member.getFirstChild().detachFromParent();
      if (!anonymous) {
        constructor.replaceChild(constructor.getFirstChild(),className.cloneNode());
      }
    }
 else {
      Node qualifiedMemberName;
      Node method;
      if (member.isMemberDef()) {
        if (member.isStaticMember()) {
          qualifiedMemberName=NodeUtil.newQName(compiler,Joiner.on("String_Node_Str").join(uniqueFullClassName,member.getString()));
        }
 else {
          qualifiedMemberName=NodeUtil.newQName(compiler,Joiner.on("String_Node_Str").join(uniqueFullClassName,"String_Node_Str",member.getString()));
        }
        method=member.getFirstChild().detachFromParent();
      }
 else       if (member.isComputedProp()) {
        if (member.isStaticMember()) {
          qualifiedMemberName=IR.getelem(NodeUtil.newQName(compiler,uniqueFullClassName),member.removeFirstChild());
        }
 else {
          qualifiedMemberName=IR.getelem(NodeUtil.newQName(compiler,Joiner.on('.').join(uniqueFullClassName,"String_Node_Str")),member.removeFirstChild());
        }
        method=member.getLastChild().detachFromParent();
      }
 else {
        throw new IllegalStateException("String_Node_Str" + member);
      }
      Node assign=IR.assign(qualifiedMemberName,method);
      assign.useSourceInfoIfMissingFromForTree(member);
      JSDocInfo info=member.getJSDocInfo();
      if (member.isStaticMember() && NodeUtil.referencesThis(assign.getLastChild())) {
        JSDocInfoBuilder memberDoc;
        if (info == null) {
          memberDoc=new JSDocInfoBuilder(true);
        }
 else {
          memberDoc=JSDocInfoBuilder.copyFrom(info);
        }
        memberDoc.recordThisType(new JSTypeExpression(new Node(Token.BANG,new Node(Token.QMARK)),member.getSourceFileName()));
        info=memberDoc.build(assign);
      }
      if (info != null) {
        info.setAssociatedNode(assign);
        assign.setJSDocInfo(info);
      }
      Node newNode=NodeUtil.newExpr(assign);
      insertionPoint.getParent().addChildAfter(newNode,insertionPoint);
      insertionPoint=newNode;
    }
  }
  Preconditions.checkNotNull(constructor);
  JSDocInfo classJSDoc=classNode.getJSDocInfo();
  JSDocInfoBuilder newInfo=(classJSDoc != null) ? JSDocInfoBuilder.copyFrom(classJSDoc) : new JSDocInfoBuilder(true);
  newInfo.recordConstructor();
  if (!superClassName.isEmpty()) {
    if (newInfo.isInterfaceRecorded()) {
      newInfo.recordExtendedInterface(new JSTypeExpression(new Node(Token.BANG,IR.string(superClassString)),superClassName.getSourceFileName()));
    }
 else {
      Node inherits=IR.call(NodeUtil.newQName(compiler,INHERITS),NodeUtil.newQName(compiler,fullClassName),NodeUtil.newQName(compiler,superClassString));
      Node inheritsCall=IR.exprResult(inherits);
      compiler.needsEs6Runtime=true;
      inheritsCall.useSourceInfoIfMissingFromForTree(classNode);
      Node enclosingStatement=NodeUtil.getEnclosingStatement(classNode);
      enclosingStatement.getParent().addChildAfter(inheritsCall,enclosingStatement);
      newInfo.recordBaseType(new JSTypeExpression(new Node(Token.BANG,IR.string(superClassString)),superClassName.getSourceFileName()));
      Node copyProps=IR.call(NodeUtil.newQName(compiler,COPY_PROP),NodeUtil.newQName(compiler,fullClassName),NodeUtil.newQName(compiler,superClassString));
      compiler.needsEs6Runtime=true;
      copyProps.useSourceInfoIfMissingFromForTree(classNode);
      enclosingStatement.getParent().addChildAfter(IR.exprResult(copyProps).srcref(classNode),enclosingStatement);
    }
  }
  if (!newInfo.isUnrestrictedRecorded() && !newInfo.isDictRecorded() && !newInfo.isStructRecorded()) {
    newInfo.recordStruct();
  }
  if (ctorJSDocInfo != null) {
    newInfo.recordSuppressions(ctorJSDocInfo.getSuppressions());
    for (    String param : ctorJSDocInfo.getParameterNames()) {
      newInfo.recordParameter(param,ctorJSDocInfo.getParameterType(param));
    }
  }
  insertionPoint=constructor;
  if (NodeUtil.isStatement(classNode)) {
    constructor.getFirstChild().setString("String_Node_Str");
    Node ctorVar=IR.var(IR.name(fullClassName),constructor);
    ctorVar.useSourceInfoIfMissingFromForTree(classNode);
    parent.replaceChild(classNode,ctorVar);
  }
 else {
    parent.replaceChild(classNode,constructor);
  }
  if (NodeUtil.isStatement(constructor)) {
    insertionPoint.setJSDocInfo(newInfo.build(insertionPoint));
  }
 else   if (parent.isName()) {
    Node var=parent.getParent();
    var.setJSDocInfo(newInfo.build(var));
  }
 else   if (constructor.getParent().isName()) {
    Node var=constructor.getParent().getParent();
    var.setJSDocInfo(newInfo.build(var));
  }
 else   if (parent.isAssign()) {
    parent.setJSDocInfo(newInfo.build(parent));
  }
 else {
    throw new IllegalStateException("String_Node_Str" + parent);
  }
  compiler.reportCodeChange();
}

Fixed version (ground truth):
/** 
 * Classes are processed in 3 phases: 1) The class name is extracted. 2) Class members are processed and rewritten. 3) The constructor is built.
 */
private void visitClass(Node classNode,Node parent){
  checkClassReassignment(classNode);
  Node className=classNode.getFirstChild();
  Node superClassName=className.getNext();
  Node classMembers=classNode.getLastChild();
  Node insertionPoint;
  if (!superClassName.isEmpty() && !superClassName.isQualifiedName()) {
    compiler.report(JSError.make(superClassName,DYNAMIC_EXTENDS_TYPE));
    return;
  }
  String fullClassName=null;
  boolean anonymous;
  if (NodeUtil.isStatement(classNode)) {
    fullClassName=className.getString();
    anonymous=false;
    insertionPoint=classNode;
  }
 else   if (parent.isAssign() && parent.getParent().isExprResult()) {
    fullClassName=parent.getFirstChild().getQualifiedName();
    if (fullClassName == null) {
      cannotConvert(parent,"String_Node_Str" + "String_Node_Str");
      return;
    }
    anonymous=true;
    insertionPoint=parent.getParent();
  }
 else   if (parent.isName()) {
    fullClassName=parent.getString();
    anonymous=true;
    insertionPoint=parent.getParent();
  }
 else {
    cannotConvert(parent,"String_Node_Str" + "String_Node_Str");
    return;
  }
  boolean useUnique=NodeUtil.isStatement(classNode) && !NodeUtil.isInFunction(classNode);
  String uniqueFullClassName=useUnique ? getUniqueClassName(fullClassName) : fullClassName;
  String superClassString=superClassName.getQualifiedName();
  Verify.verify(NodeUtil.isStatement(insertionPoint));
  Node constructor=null;
  JSDocInfo ctorJSDocInfo=null;
  for (  Node member : classMembers.children()) {
    if (member.isEmpty()) {
      continue;
    }
    if (member.isMemberDef() && member.getString().equals("String_Node_Str")) {
      ctorJSDocInfo=member.getJSDocInfo();
      constructor=member.getFirstChild().detachFromParent();
      if (!anonymous) {
        constructor.replaceChild(constructor.getFirstChild(),className.cloneNode());
      }
    }
 else {
      Node qualifiedMemberName;
      Node method;
      if (member.isMemberDef()) {
        if (member.isStaticMember()) {
          qualifiedMemberName=NodeUtil.newQName(compiler,Joiner.on("String_Node_Str").join(uniqueFullClassName,member.getString()));
        }
 else {
          qualifiedMemberName=NodeUtil.newQName(compiler,Joiner.on("String_Node_Str").join(uniqueFullClassName,"String_Node_Str",member.getString()));
        }
        method=member.getFirstChild().detachFromParent();
      }
 else       if (member.isComputedProp()) {
        if (member.isStaticMember()) {
          qualifiedMemberName=IR.getelem(NodeUtil.newQName(compiler,uniqueFullClassName),member.removeFirstChild());
        }
 else {
          qualifiedMemberName=IR.getelem(NodeUtil.newQName(compiler,Joiner.on('.').join(uniqueFullClassName,"String_Node_Str")),member.removeFirstChild());
        }
        method=member.getLastChild().detachFromParent();
      }
 else {
        throw new IllegalStateException("String_Node_Str" + member);
      }
      Node assign=IR.assign(qualifiedMemberName,method);
      assign.useSourceInfoIfMissingFromForTree(member);
      JSDocInfo info=member.getJSDocInfo();
      if (member.isStaticMember() && NodeUtil.referencesThis(assign.getLastChild())) {
        JSDocInfoBuilder memberDoc;
        if (info == null) {
          memberDoc=new JSDocInfoBuilder(true);
        }
 else {
          memberDoc=JSDocInfoBuilder.copyFrom(info);
        }
        memberDoc.recordThisType(new JSTypeExpression(new Node(Token.BANG,new Node(Token.QMARK)),member.getSourceFileName()));
        info=memberDoc.build(assign);
      }
      if (info != null) {
        info.setAssociatedNode(assign);
        assign.setJSDocInfo(info);
      }
      Node newNode=NodeUtil.newExpr(assign);
      insertionPoint.getParent().addChildAfter(newNode,insertionPoint);
      insertionPoint=newNode;
    }
  }
  Preconditions.checkNotNull(constructor);
  JSDocInfo classJSDoc=classNode.getJSDocInfo();
  JSDocInfoBuilder newInfo=(classJSDoc != null) ? JSDocInfoBuilder.copyFrom(classJSDoc) : new JSDocInfoBuilder(true);
  newInfo.recordConstructor();
  if (!superClassName.isEmpty()) {
    if (newInfo.isInterfaceRecorded()) {
      newInfo.recordExtendedInterface(new JSTypeExpression(new Node(Token.BANG,IR.string(superClassString)),superClassName.getSourceFileName()));
    }
 else {
      Node inherits=IR.call(NodeUtil.newQName(compiler,INHERITS),NodeUtil.newQName(compiler,fullClassName),NodeUtil.newQName(compiler,superClassString));
      Node inheritsCall=IR.exprResult(inherits);
      compiler.needsEs6Runtime=true;
      inheritsCall.useSourceInfoIfMissingFromForTree(classNode);
      Node enclosingStatement=NodeUtil.getEnclosingStatement(classNode);
      enclosingStatement.getParent().addChildAfter(inheritsCall,enclosingStatement);
      newInfo.recordBaseType(new JSTypeExpression(new Node(Token.BANG,IR.string(superClassString)),superClassName.getSourceFileName()));
      Node copyProps=IR.call(NodeUtil.newQName(compiler,COPY_PROP),NodeUtil.newQName(compiler,fullClassName),NodeUtil.newQName(compiler,superClassString));
      compiler.needsEs6Runtime=true;
      copyProps.useSourceInfoIfMissingFromForTree(classNode);
      enclosingStatement.getParent().addChildAfter(IR.exprResult(copyProps).srcref(classNode),enclosingStatement);
    }
  }
  if (!newInfo.isUnrestrictedRecorded() && !newInfo.isDictRecorded() && !newInfo.isStructRecorded()) {
    newInfo.recordStruct();
  }
  if (ctorJSDocInfo != null) {
    newInfo.recordSuppressions(ctorJSDocInfo.getSuppressions());
    for (    String param : ctorJSDocInfo.getParameterNames()) {
      newInfo.recordParameter(param,ctorJSDocInfo.getParameterType(param));
    }
  }
  insertionPoint=constructor;
  if (NodeUtil.isStatement(classNode)) {
    constructor.getFirstChild().setString("String_Node_Str");
    Node ctorVar=IR.var(IR.name(fullClassName),constructor);
    ctorVar.useSourceInfoIfMissingFromForTree(classNode);
    parent.replaceChild(classNode,ctorVar);
  }
 else {
    parent.replaceChild(classNode,constructor);
  }
  if (NodeUtil.isStatement(constructor)) {
    insertionPoint.setJSDocInfo(newInfo.build(insertionPoint));
  }
 else   if (parent.isName()) {
    Node var=parent.getParent();
    var.setJSDocInfo(newInfo.build(var));
  }
 else   if (constructor.getParent().isName()) {
    Node var=constructor.getParent().getParent();
    var.setJSDocInfo(newInfo.build(var));
  }
 else   if (parent.isAssign()) {
    parent.setJSDocInfo(newInfo.build(parent));
  }
 else {
    throw new IllegalStateException("String_Node_Str" + parent);
  }
  compiler.reportCodeChange();
}