Program: 186752
Project: 186752
Buggy source:
/** 
 * Find all methods which might get invoked for a given methodRef. This does not use the callgraph to eliminate methods. If you want a more precise result, use   {@link #findImplementations(InvokeSite,CallString)} and use callgraph thinning first.<p> Note that this method is slightly different from  {@link MethodInfo#getImplementations(boolean)}, since it returns only methods for subclasses of the invokee class, not of the implementing class. </p> <p>To handle invocations of super-methods correctly, use   {@link #findImplementations(InvokeSite)}instead.</p>
 * @see #findImplementations(InvokeSite)
 * @param invokee the method to resolve.
 * @return all possible implementations.
 */
public Set<MethodInfo> findImplementations(final MethodRef invokee){
  final Set<MethodInfo> methods=new HashSet<MethodInfo>();
  final MethodInfo method=invokee.getMethodInfo();
  if (method != null && (method.isStatic() || method.isPrivate())) {
    methods.add(method);
    return methods;
  }
  final String methodSig=invokee.getMethodSignature();
  final ClassInfo invokeeClass=invokee.getClassRef().getClassInfo();
  if (invokeeClass == null) {
    logger.debug("String_Node_Str" + invokee.toString());
    return methods;
  }
  boolean undefinedBaseMethod=false;
  if (invokeeClass.getMethodInfo(methodSig) == null) {
    if (method != null && !method.isAbstract()) {
      methods.add(method);
    }
 else     if (method == null) {
      if (invokeeClass.isFullyKnown(true)) {
        throw new JavaClassFormatError("String_Node_Str" + invokee.toString());
      }
 else {
        logger.debug("String_Node_Str" + invokee.toString());
        undefinedBaseMethod=true;
      }
    }
  }
  ClassVisitor visitor=new ClassVisitor(){
    public boolean visitClass(    ClassInfo classInfo){
      MethodInfo m=classInfo.getMethodInfo(methodSig);
      if (m != null) {
        if (m.isPrivate() && !classInfo.equals(invokeeClass)) {
          logger.error("String_Node_Str" + m.getMethodSignature() + "String_Node_Str"+ classInfo.getClassName()+ "String_Node_Str"+ invokee.getClassName());
        }
        if (!m.isAbstract() && (method == null || m.overrides(method,false))) {
          methods.add(m);
        }
      }
      return true;
    }
    public void finishClass(    ClassInfo classInfo){
    }
  }
;
  ClassHierarchyTraverser traverser=new ClassHierarchyTraverser(visitor);
  traverser.setVisitSubclasses(true,true);
  traverser.traverseDown(invokeeClass);
  if (undefinedBaseMethod && methods.size() > 0) {
    throw new JavaClassFormatError("String_Node_Str" + invokee + "String_Node_Str");
  }
  return methods;
}

Fixed version (ground truth):
/** 
 * Find all methods which might get invoked for a given methodRef. This does not use the callgraph to eliminate methods. If you want a more precise result, use   {@link #findImplementations(InvokeSite,CallString)} and use callgraph thinning first.<p> Note that this method is slightly different from  {@link MethodInfo#getImplementations(boolean)}, since it returns only methods for subclasses of the invokee class, not of the implementing class. </p> <p>To handle invocations of super-methods correctly, use   {@link #findImplementations(InvokeSite)}instead.</p>
 * @see #findImplementations(InvokeSite)
 * @param invokee the method to resolve.
 * @return all possible implementations.
 */
public Set<MethodInfo> findImplementations(final MethodRef invokee){
  final Set<MethodInfo> methods=new HashSet<MethodInfo>();
  final MethodInfo method=invokee.getMethodInfo();
  if (method != null && (method.isStatic() || method.isPrivate())) {
    methods.add(method);
    return methods;
  }
  final String methodSig=invokee.getMethodSignature();
  final ClassInfo invokeeClass=invokee.getClassRef().getClassInfo();
  if (invokeeClass == null) {
    logger.debug("String_Node_Str" + invokee.toString());
    return methods;
  }
  boolean undefinedBaseMethod=false;
  if (invokeeClass.getMethodInfo(methodSig) == null) {
    if (method != null && !method.isAbstract()) {
      methods.add(method);
    }
 else     if (method == null) {
      if (invokeeClass.isFullyKnown(true)) {
        throw new JavaClassFormatError("String_Node_Str" + invokee.toString());
      }
 else {
        logger.debug("String_Node_Str" + invokee.toString());
        undefinedBaseMethod=true;
      }
    }
  }
  ClassVisitor visitor=new ClassVisitor(){
    public boolean visitClass(    ClassInfo classInfo){
      MethodInfo m;
      if (invokeeClass.isInterface() && !classInfo.isInterface()) {
        m=classInfo.getMethodInfoInherited(methodSig,true);
      }
 else {
        m=classInfo.getMethodInfo(methodSig);
      }
      if (m != null) {
        if (m.isPrivate() && !classInfo.equals(invokeeClass)) {
          logger.error("String_Node_Str" + m.getMethodSignature() + "String_Node_Str"+ classInfo.getClassName()+ "String_Node_Str"+ invokee.getClassName());
        }
        if (!m.isAbstract() && (method == null || m.overrides(method,false))) {
          methods.add(m);
        }
      }
      return true;
    }
    public void finishClass(    ClassInfo classInfo){
    }
  }
;
  ClassHierarchyTraverser traverser=new ClassHierarchyTraverser(visitor);
  traverser.setVisitSubclasses(true,true);
  traverser.traverseDown(invokeeClass);
  if (undefinedBaseMethod && methods.size() > 0) {
    throw new JavaClassFormatError("String_Node_Str" + invokee + "String_Node_Str");
  }
  return methods;
}