Program: 27197
Project: 27197
Buggy source:
private void maybeProcessClassBaseCall(NodeTraversal t,Node n){
  Node callTarget=n.getFirstChild();
  Node baseContainerNode=callTarget.getFirstChild();
  if (!baseContainerNode.isUnscopedQualifiedName()) {
    return;
  }
  String baseContainer=callTarget.getFirstChild().getQualifiedName();
  Node enclosingFnNameNode=getEnclosingDeclNameNode(n);
  if (enclosingFnNameNode == null || !enclosingFnNameNode.isUnscopedQualifiedName()) {
    if (knownClosureSubclasses.contains(baseContainer)) {
      reportBadBaseMethodUse(t,n,baseContainer,"String_Node_Str");
    }
 else     if (baseUsedInClass(n)) {
      Node clazz=NodeUtil.getEnclosingClass(n);
      if ((clazz.getFirstChild().isName() && clazz.getFirstChild().getString().equals(baseContainer)) || (clazz.getSecondChild().isName() && clazz.getSecondChild().getString().equals(baseContainer))) {
        reportBadGoogBaseUse(t,n,"String_Node_Str");
      }
    }
    return;
  }
  if (baseUsedInClass(n)) {
    reportBadGoogBaseUse(t,n,"String_Node_Str");
    return;
  }
  String enclosingQname=enclosingFnNameNode.getQualifiedName();
  if (!enclosingQname.contains("String_Node_Str")) {
    if (!enclosingQname.equals(baseContainer)) {
      if (knownClosureSubclasses.contains(baseContainer)) {
        reportBadBaseMethodUse(t,n,baseContainer,"String_Node_Str" + baseContainer + "String_Node_Str");
      }
      return;
    }
    Node enclosingParent=enclosingFnNameNode.getParent();
    Node maybeInheritsExpr=(enclosingParent.isAssign() ? enclosingParent.getParent() : enclosingParent).getNext();
    while (maybeInheritsExpr != null && maybeInheritsExpr.isEmpty()) {
      maybeInheritsExpr=maybeInheritsExpr.getNext();
    }
    Node baseClassNode=null;
    if (maybeInheritsExpr != null && maybeInheritsExpr.isExprResult() && maybeInheritsExpr.getFirstChild().isCall()) {
      Node callNode=maybeInheritsExpr.getFirstChild();
      if (callNode.getFirstChild().matchesQualifiedName("String_Node_Str") && callNode.getLastChild().isQualifiedName()) {
        baseClassNode=callNode.getLastChild();
      }
    }
    if (baseClassNode == null) {
      return;
    }
    Node callee=n.getFirstChild();
    Node thisArg=callee.getNext();
    if (thisArg == null || !thisArg.isThis()) {
      reportBadBaseMethodUse(t,n,baseContainer,"String_Node_Str");
      return;
    }
    Node methodNameNode=thisArg.getNext();
    if (methodNameNode == null || !methodNameNode.isString() || !methodNameNode.getString().equals("String_Node_Str")) {
      reportBadBaseMethodUse(t,n,baseContainer,"String_Node_Str");
      return;
    }
    n.replaceChild(callee,NodeUtil.newQName(compiler,baseClassNode.getQualifiedName() + "String_Node_Str",callee,enclosingQname + "String_Node_Str"));
    n.removeChild(methodNameNode);
    compiler.reportChangeToEnclosingScope(n);
  }
 else {
    if (!knownClosureSubclasses.contains(baseContainer)) {
      return;
    }
    boolean misuseOfBase=!enclosingFnNameNode.getFirstFirstChild().matchesQualifiedName(baseContainer);
    if (misuseOfBase) {
      reportBadBaseMethodUse(t,n,baseContainer,"String_Node_Str" + baseContainer + "String_Node_Str");
      return;
    }
    Node callee=n.getFirstChild();
    Node thisArg=callee.getNext();
    if (thisArg == null || !thisArg.isThis()) {
      reportBadBaseMethodUse(t,n,baseContainer,"String_Node_Str");
      return;
    }
    Node methodNameNode=thisArg.getNext();
    if (methodNameNode == null || !methodNameNode.isString()) {
      reportBadBaseMethodUse(t,n,baseContainer,"String_Node_Str");
      return;
    }
    String methodName=methodNameNode.getString();
    String ending="String_Node_Str" + methodName;
    if (enclosingQname == null || !enclosingQname.endsWith(ending)) {
      reportBadBaseMethodUse(t,n,baseContainer,"String_Node_Str" + methodName);
      return;
    }
    Node className=enclosingFnNameNode.getFirstFirstChild();
    n.replaceChild(callee,NodeUtil.newQName(compiler,className.getQualifiedName() + "String_Node_Str" + methodName+ "String_Node_Str",callee,enclosingQname + "String_Node_Str"));
    n.removeChild(methodNameNode);
    compiler.reportChangeToEnclosingScope(n);
  }
}

Fixed version (ground truth):
private void maybeProcessClassBaseCall(NodeTraversal t,Node n){
  Node callTarget=n.getFirstChild();
  Node baseContainerNode=callTarget.getFirstChild();
  if (!baseContainerNode.isUnscopedQualifiedName()) {
    return;
  }
  String baseContainer=callTarget.getFirstChild().getQualifiedName();
  Node enclosingFnNameNode=getEnclosingDeclNameNode(n);
  if (enclosingFnNameNode == null || !enclosingFnNameNode.isUnscopedQualifiedName()) {
    if (knownClosureSubclasses.contains(baseContainer)) {
      reportBadBaseMethodUse(t,n,baseContainer,"String_Node_Str");
    }
 else     if (baseUsedInClass(n)) {
      Node clazz=NodeUtil.getEnclosingClass(n);
      if ((clazz.getFirstChild().isName() && clazz.getFirstChild().getString().equals(baseContainer)) || (clazz.getSecondChild().isName() && clazz.getSecondChild().getString().equals(baseContainer))) {
        reportBadBaseMethodUse(t,n,clazz.getFirstChild().getString(),"String_Node_Str");
      }
    }
    return;
  }
  if (baseUsedInClass(n)) {
    reportBadGoogBaseUse(t,n,"String_Node_Str");
    return;
  }
  String enclosingQname=enclosingFnNameNode.getQualifiedName();
  if (!enclosingQname.contains("String_Node_Str")) {
    if (!enclosingQname.equals(baseContainer)) {
      if (knownClosureSubclasses.contains(baseContainer)) {
        reportBadBaseMethodUse(t,n,baseContainer,"String_Node_Str" + baseContainer + "String_Node_Str");
      }
      return;
    }
    Node enclosingParent=enclosingFnNameNode.getParent();
    Node maybeInheritsExpr=(enclosingParent.isAssign() ? enclosingParent.getParent() : enclosingParent).getNext();
    while (maybeInheritsExpr != null && maybeInheritsExpr.isEmpty()) {
      maybeInheritsExpr=maybeInheritsExpr.getNext();
    }
    Node baseClassNode=null;
    if (maybeInheritsExpr != null && maybeInheritsExpr.isExprResult() && maybeInheritsExpr.getFirstChild().isCall()) {
      Node callNode=maybeInheritsExpr.getFirstChild();
      if (callNode.getFirstChild().matchesQualifiedName("String_Node_Str") && callNode.getLastChild().isQualifiedName()) {
        baseClassNode=callNode.getLastChild();
      }
    }
    if (baseClassNode == null) {
      return;
    }
    Node callee=n.getFirstChild();
    Node thisArg=callee.getNext();
    if (thisArg == null || !thisArg.isThis()) {
      reportBadBaseMethodUse(t,n,baseContainer,"String_Node_Str");
      return;
    }
    Node methodNameNode=thisArg.getNext();
    if (methodNameNode == null || !methodNameNode.isString() || !methodNameNode.getString().equals("String_Node_Str")) {
      reportBadBaseMethodUse(t,n,baseContainer,"String_Node_Str");
      return;
    }
    n.replaceChild(callee,NodeUtil.newQName(compiler,baseClassNode.getQualifiedName() + "String_Node_Str",callee,enclosingQname + "String_Node_Str"));
    n.removeChild(methodNameNode);
    compiler.reportChangeToEnclosingScope(n);
  }
 else {
    if (!knownClosureSubclasses.contains(baseContainer)) {
      return;
    }
    boolean misuseOfBase=!enclosingFnNameNode.getFirstFirstChild().matchesQualifiedName(baseContainer);
    if (misuseOfBase) {
      reportBadBaseMethodUse(t,n,baseContainer,"String_Node_Str" + baseContainer + "String_Node_Str");
      return;
    }
    Node callee=n.getFirstChild();
    Node thisArg=callee.getNext();
    if (thisArg == null || !thisArg.isThis()) {
      reportBadBaseMethodUse(t,n,baseContainer,"String_Node_Str");
      return;
    }
    Node methodNameNode=thisArg.getNext();
    if (methodNameNode == null || !methodNameNode.isString()) {
      reportBadBaseMethodUse(t,n,baseContainer,"String_Node_Str");
      return;
    }
    String methodName=methodNameNode.getString();
    String ending="String_Node_Str" + methodName;
    if (enclosingQname == null || !enclosingQname.endsWith(ending)) {
      reportBadBaseMethodUse(t,n,baseContainer,"String_Node_Str" + methodName);
      return;
    }
    Node className=enclosingFnNameNode.getFirstFirstChild();
    n.replaceChild(callee,NodeUtil.newQName(compiler,className.getQualifiedName() + "String_Node_Str" + methodName+ "String_Node_Str",callee,enclosingQname + "String_Node_Str"));
    n.removeChild(methodNameNode);
    compiler.reportChangeToEnclosingScope(n);
  }
}