Program: 27525
Project: 27525
Buggy source:
/** 
 * Classes are processed in 3 phases: <ol> <li>The class name is extracted. <li>Class members are processed and rewritten. <li>The constructor is built. </ol>
 */
private void visitClass(Node classNode,Node parent){
  checkClassReassignment(classNode);
  ClassDeclarationMetadata metadata=ClassDeclarationMetadata.create(classNode,parent);
  if (metadata == null || metadata.fullClassName == null) {
    cannotConvert(parent,"String_Node_Str" + "String_Node_Str");
    return;
  }
  if (metadata.hasSuperClass() && !metadata.superClassNameNode.isQualifiedName()) {
    compiler.report(JSError.make(metadata.superClassNameNode,DYNAMIC_EXTENDS_TYPE));
    return;
  }
  boolean useUnique=NodeUtil.isStatement(classNode) && !NodeUtil.isInFunction(classNode);
  String uniqueFullClassName=useUnique ? getUniqueClassName(metadata.fullClassName) : metadata.fullClassName;
  Node classNameAccess=NodeUtil.newQName(compiler,uniqueFullClassName);
  Node prototypeAccess=NodeUtil.newPropertyAccess(compiler,classNameAccess,"String_Node_Str");
  Preconditions.checkState(NodeUtil.isStatement(metadata.insertionPoint),"String_Node_Str",metadata.insertionPoint);
  Node constructor=null;
  JSDocInfo ctorJSDocInfo=null;
  Node classMembers=classNode.getLastChild();
  Map<String,JSTypeExpression> membersToDeclare=new LinkedHashMap<>();
  for (  Node member : classMembers.children()) {
    if (member.isEmpty()) {
      continue;
    }
    Preconditions.checkState(member.isMemberFunctionDef() || member.isGetterDef() || member.isSetterDef()|| (member.isComputedProp() && !member.getBooleanProp(Node.COMPUTED_PROP_VARIABLE)),"String_Node_Str",member);
    if (member.isGetterDef() || member.isSetterDef()) {
      if (member.isStaticMember()) {
        compiler.report(JSError.make(member,CANNOT_CONVERT_YET,"String_Node_Str"));
      }
      JSTypeExpression typeExpr=getTypeFromGetterOrSetter(member).clone();
      addToDefinePropertiesObject(metadata,member);
      JSTypeExpression existingType=membersToDeclare.get(member.getString());
      if (existingType != null && !existingType.equals(typeExpr)) {
        compiler.report(JSError.make(member,CONFLICTING_GETTER_SETTER_TYPE));
      }
 else {
        membersToDeclare.put(member.getString(),typeExpr);
      }
    }
 else     if (member.isMemberFunctionDef() && member.getString().equals("String_Node_Str")) {
      ctorJSDocInfo=member.getJSDocInfo();
      constructor=member.getFirstChild().detachFromParent();
      if (!metadata.anonymous) {
        constructor.replaceChild(constructor.getFirstChild(),metadata.classNameNode.cloneNode());
      }
    }
 else {
      Node qualifiedMemberAccess=getQualifiedMemberAccess(compiler,member,classNameAccess,prototypeAccess);
      Node method=member.getLastChild().detachFromParent();
      Node assign=IR.assign(qualifiedMemberAccess,method);
      assign.useSourceInfoIfMissingFromForTree(member);
      JSDocInfo info=member.getJSDocInfo();
      if (member.isStaticMember() && NodeUtil.referencesThis(assign.getLastChild())) {
        JSDocInfoBuilder memberDoc=JSDocInfoBuilder.maybeCopyFrom(info);
        memberDoc.recordThisType(new JSTypeExpression(new Node(Token.BANG,new Node(Token.QMARK)),member.getSourceFileName()));
        info=memberDoc.build();
      }
      if (info != null) {
        assign.setJSDocInfo(info);
      }
      Node newNode=NodeUtil.newExpr(assign);
      metadata.insertStaticMember(newNode);
    }
  }
  for (  Map.Entry<String,JSTypeExpression> entry : membersToDeclare.entrySet()) {
    String declaredMember=entry.getKey();
    Node declaration=IR.getprop(prototypeAccess.cloneTree(),IR.string(declaredMember));
    JSDocInfoBuilder declInfo=new JSDocInfoBuilder(true);
    declInfo.recordType(entry.getValue());
    declaration.setJSDocInfo(declInfo.build());
    metadata.insertStaticMember(IR.exprResult(declaration).useSourceInfoIfMissingFromForTree(classNode));
  }
  if (metadata.defineProperties.hasChildren()) {
    Node definePropsCall=IR.exprResult(IR.call(NodeUtil.newQName(compiler,"String_Node_Str"),prototypeAccess.cloneTree(),metadata.defineProperties));
    definePropsCall.useSourceInfoIfMissingFromForTree(classNode);
    metadata.insertStaticMember(definePropsCall);
  }
  Preconditions.checkNotNull(constructor);
  JSDocInfo classJSDoc=NodeUtil.getBestJSDocInfo(classNode);
  JSDocInfoBuilder newInfo=JSDocInfoBuilder.maybeCopyFrom(classJSDoc);
  newInfo.recordConstructor();
  if (metadata.hasSuperClass()) {
    String superClassString=metadata.superClassNameNode.getQualifiedName();
    if (newInfo.isInterfaceRecorded()) {
      newInfo.recordExtendedInterface(new JSTypeExpression(new Node(Token.BANG,IR.string(superClassString)),metadata.superClassNameNode.getSourceFileName()));
    }
 else {
      Node inherits=IR.call(NodeUtil.newQName(compiler,INHERITS),NodeUtil.newQName(compiler,metadata.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)),metadata.superClassNameNode.getSourceFileName()));
      Node copyProps=IR.call(NodeUtil.newQName(compiler,COPY_PROP),NodeUtil.newQName(compiler,metadata.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));
    }
    newInfo.mergePropertyBitfieldFrom(ctorJSDocInfo);
  }
  if (NodeUtil.isStatement(classNode)) {
    constructor.getFirstChild().setString("String_Node_Str");
    Node ctorVar=IR.var(IR.name(metadata.fullClassName),constructor);
    ctorVar.useSourceInfoIfMissingFromForTree(classNode);
    parent.replaceChild(classNode,ctorVar);
  }
 else {
    parent.replaceChild(classNode,constructor);
  }
  if (NodeUtil.isStatement(constructor)) {
    constructor.setJSDocInfo(newInfo.build());
  }
 else   if (parent.isName()) {
    Node var=parent.getParent();
    var.setJSDocInfo(newInfo.build());
  }
 else   if (constructor.getParent().isName()) {
    Node var=constructor.getParent().getParent();
    var.setJSDocInfo(newInfo.build());
  }
 else   if (parent.isAssign()) {
    parent.setJSDocInfo(newInfo.build());
  }
 else {
    throw new IllegalStateException("String_Node_Str" + parent);
  }
  compiler.reportCodeChange();
}

Fixed version (ground truth):
/** 
 * Classes are processed in 3 phases: <ol> <li>The class name is extracted. <li>Class members are processed and rewritten. <li>The constructor is built. </ol>
 */
private void visitClass(Node classNode,Node parent){
  checkClassReassignment(classNode);
  ClassDeclarationMetadata metadata=ClassDeclarationMetadata.create(classNode,parent);
  if (metadata == null || metadata.fullClassName == null) {
    cannotConvert(parent,"String_Node_Str" + "String_Node_Str");
    return;
  }
  if (metadata.hasSuperClass() && !metadata.superClassNameNode.isQualifiedName()) {
    compiler.report(JSError.make(metadata.superClassNameNode,DYNAMIC_EXTENDS_TYPE));
    return;
  }
  boolean useUnique=NodeUtil.isStatement(classNode) && !NodeUtil.isInFunction(classNode);
  String uniqueFullClassName=useUnique ? getUniqueClassName(metadata.fullClassName) : metadata.fullClassName;
  Node classNameAccess=NodeUtil.newQName(compiler,uniqueFullClassName);
  Node prototypeAccess=NodeUtil.newPropertyAccess(compiler,classNameAccess,"String_Node_Str");
  Preconditions.checkState(NodeUtil.isStatement(metadata.insertionPoint),"String_Node_Str",metadata.insertionPoint);
  Node constructor=null;
  JSDocInfo ctorJSDocInfo=null;
  Node classMembers=classNode.getLastChild();
  Map<String,JSTypeExpression> membersToDeclare=new LinkedHashMap<>();
  for (  Node member : classMembers.children()) {
    if (member.isEmpty()) {
      continue;
    }
    Preconditions.checkState(member.isMemberFunctionDef() || member.isGetterDef() || member.isSetterDef()|| (member.isComputedProp() && !member.getBooleanProp(Node.COMPUTED_PROP_VARIABLE)),"String_Node_Str",member);
    if (member.isGetterDef() || member.isSetterDef()) {
      if (member.isStaticMember()) {
        compiler.report(JSError.make(member,CANNOT_CONVERT_YET,"String_Node_Str"));
      }
      JSTypeExpression typeExpr=getTypeFromGetterOrSetter(member).clone();
      addToDefinePropertiesObject(metadata,member);
      JSTypeExpression existingType=membersToDeclare.get(member.getString());
      if (existingType != null && !existingType.equals(typeExpr)) {
        compiler.report(JSError.make(member,CONFLICTING_GETTER_SETTER_TYPE,member.getString()));
      }
 else {
        membersToDeclare.put(member.getString(),typeExpr);
      }
    }
 else     if (member.isMemberFunctionDef() && member.getString().equals("String_Node_Str")) {
      ctorJSDocInfo=member.getJSDocInfo();
      constructor=member.getFirstChild().detachFromParent();
      if (!metadata.anonymous) {
        constructor.replaceChild(constructor.getFirstChild(),metadata.classNameNode.cloneNode());
      }
    }
 else {
      Node qualifiedMemberAccess=getQualifiedMemberAccess(compiler,member,classNameAccess,prototypeAccess);
      Node method=member.getLastChild().detachFromParent();
      Node assign=IR.assign(qualifiedMemberAccess,method);
      assign.useSourceInfoIfMissingFromForTree(member);
      JSDocInfo info=member.getJSDocInfo();
      if (member.isStaticMember() && NodeUtil.referencesThis(assign.getLastChild())) {
        JSDocInfoBuilder memberDoc=JSDocInfoBuilder.maybeCopyFrom(info);
        memberDoc.recordThisType(new JSTypeExpression(new Node(Token.BANG,new Node(Token.QMARK)),member.getSourceFileName()));
        info=memberDoc.build();
      }
      if (info != null) {
        assign.setJSDocInfo(info);
      }
      Node newNode=NodeUtil.newExpr(assign);
      metadata.insertStaticMember(newNode);
    }
  }
  for (  Map.Entry<String,JSTypeExpression> entry : membersToDeclare.entrySet()) {
    String declaredMember=entry.getKey();
    Node declaration=IR.getprop(prototypeAccess.cloneTree(),IR.string(declaredMember));
    JSDocInfoBuilder declInfo=new JSDocInfoBuilder(true);
    declInfo.recordType(entry.getValue());
    declaration.setJSDocInfo(declInfo.build());
    metadata.insertStaticMember(IR.exprResult(declaration).useSourceInfoIfMissingFromForTree(classNode));
  }
  if (metadata.defineProperties.hasChildren()) {
    Node definePropsCall=IR.exprResult(IR.call(NodeUtil.newQName(compiler,"String_Node_Str"),prototypeAccess.cloneTree(),metadata.defineProperties));
    definePropsCall.useSourceInfoIfMissingFromForTree(classNode);
    metadata.insertStaticMember(definePropsCall);
  }
  Preconditions.checkNotNull(constructor);
  JSDocInfo classJSDoc=NodeUtil.getBestJSDocInfo(classNode);
  JSDocInfoBuilder newInfo=JSDocInfoBuilder.maybeCopyFrom(classJSDoc);
  newInfo.recordConstructor();
  if (metadata.hasSuperClass()) {
    String superClassString=metadata.superClassNameNode.getQualifiedName();
    if (newInfo.isInterfaceRecorded()) {
      newInfo.recordExtendedInterface(new JSTypeExpression(new Node(Token.BANG,IR.string(superClassString)),metadata.superClassNameNode.getSourceFileName()));
    }
 else {
      Node inherits=IR.call(NodeUtil.newQName(compiler,INHERITS),NodeUtil.newQName(compiler,metadata.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)),metadata.superClassNameNode.getSourceFileName()));
      Node copyProps=IR.call(NodeUtil.newQName(compiler,COPY_PROP),NodeUtil.newQName(compiler,metadata.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));
    }
    newInfo.mergePropertyBitfieldFrom(ctorJSDocInfo);
  }
  if (NodeUtil.isStatement(classNode)) {
    constructor.getFirstChild().setString("String_Node_Str");
    Node ctorVar=IR.var(IR.name(metadata.fullClassName),constructor);
    ctorVar.useSourceInfoIfMissingFromForTree(classNode);
    parent.replaceChild(classNode,ctorVar);
  }
 else {
    parent.replaceChild(classNode,constructor);
  }
  if (NodeUtil.isStatement(constructor)) {
    constructor.setJSDocInfo(newInfo.build());
  }
 else   if (parent.isName()) {
    Node var=parent.getParent();
    var.setJSDocInfo(newInfo.build());
  }
 else   if (constructor.getParent().isName()) {
    Node var=constructor.getParent().getParent();
    var.setJSDocInfo(newInfo.build());
  }
 else   if (parent.isAssign()) {
    parent.setJSDocInfo(newInfo.build());
  }
 else {
    throw new IllegalStateException("String_Node_Str" + parent);
  }
  compiler.reportCodeChange();
}