| 1 19 20 package edu.umd.cs.findbugs.detect; 21 22 import java.util.Set ; 23 24 import org.apache.bcel.classfile.Code; 25 import org.apache.bcel.classfile.Field; 26 import org.apache.bcel.classfile.JavaClass; 27 28 import edu.umd.cs.findbugs.BugInstance; 29 import edu.umd.cs.findbugs.BugReporter; 30 import edu.umd.cs.findbugs.BytecodeScanningDetector; 31 import edu.umd.cs.findbugs.OpcodeStack; 32 import edu.umd.cs.findbugs.ba.XFactory; 33 import edu.umd.cs.findbugs.ba.XMethod; 34 35 public class ConfusionBetweenInheritedAndOuterMethod extends BytecodeScanningDetector { 36 37 38 BugReporter bugReporter; 39 public ConfusionBetweenInheritedAndOuterMethod(BugReporter bugReporter) { 40 this.bugReporter = bugReporter; 41 } 42 43 44 @Override  45 public void visitJavaClass(JavaClass obj) { 46 hasThisDollarZero = false; 47 if (obj.getClassName().indexOf('$') >= 0) super.visitJavaClass(obj); 49 50 } 51 52 boolean hasThisDollarZero; 53 54 @Override  55 public void visit(Field f) { 56 if (f.getName().equals("this$0")) hasThisDollarZero = true; 57 } 58 OpcodeStack stack = new OpcodeStack(); 59 @Override  60 public void visit(Code obj) { 61 if (hasThisDollarZero) { 62 stack.resetForMethodEntry(this); 63 super.visit(obj); 64 } 65 } 66 67 private static String stripLastDollar(String s) { 68 int i = s.lastIndexOf('$'); 69 if (i == -1) throw new IllegalArgumentException (); 70 return s.substring(0,i); 71 } 72 @Override  73 public void sawOpcode(int seen) { 74 stack.mergeJumps(this); 75 try { 76 if (seen != INVOKEVIRTUAL) return; 77 if (!getClassName().equals(getClassConstantOperand())) return; 78 XMethod invokedMethod = XFactory.createXMethod(getDottedClassConstantOperand(), getNameConstantOperand(), getSigConstantOperand(), false); 79 if (invokedMethod.isResolved() && invokedMethod.getClassName().equals(getDottedClassConstantOperand())) { 80 return; 82 } 83 String possibleTargetClass = getDottedClassName(); 85 String superClassName = getDottedSuperclassName(); 86 while(true) { 87 int i = possibleTargetClass.lastIndexOf('$'); 88 if (i == -1) break; 89 possibleTargetClass = possibleTargetClass.substring(0,i); 90 if (possibleTargetClass.equals(superClassName)) break; 91 XMethod alternativeMethod = XFactory.createXMethod(possibleTargetClass, getNameConstantOperand(), getSigConstantOperand(), false); 92 if (alternativeMethod.isResolved() && alternativeMethod.getClassName().equals(possibleTargetClass)) { 93 String targetPackage = invokedMethod.getPackageName(); 94 String alternativePackage = alternativeMethod.getPackageName(); 95 int priority = HIGH_PRIORITY; 96 if (targetPackage.equals(alternativePackage)) priority++; 97 if (targetPackage.startsWith("javax.swing") || targetPackage.startsWith("java.awt")) 98 priority+=2; 99 if (invokedMethod.getName().equals(getMethodName())) priority++; 100 101 bugReporter.reportBug(new BugInstance(this, "IA_AMBIGUOUS_INVOCATION_OF_INHERITED_OR_OUTER_METHOD", priority) 102 .addClassAndMethod(this) 103 .addMethod(invokedMethod).describe("METHOD_INHERITED") 104 .addMethod(alternativeMethod).describe("METHOD_ALTERNATIVE_TARGET") 105 .addSourceLine(this, getPC())); 106 break; 107 } 108 } 109 110 111 } finally { 112 stack.sawOpcode(this, seen); 113 } 114 } 115 116 } 117 | Popular Tags |