KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > umd > cs > findbugs > detect > ConfusionBetweenInheritedAndOuterMethod


1 /*
2  * FindBugs - Find bugs in Java programs
3  * Copyright (C) 2005, University of Maryland
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */

19
20 package edu.umd.cs.findbugs.detect;
21
22 import java.util.Set JavaDoc;
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 JavaDoc
45          public void visitJavaClass(JavaClass obj) {
46         hasThisDollarZero = false;
47         // totally skip methods not defined in inner classes
48
if (obj.getClassName().indexOf('$') >= 0) super.visitJavaClass(obj);
49         
50     }
51
52     boolean hasThisDollarZero;
53     
54     @Override JavaDoc
55     public void visit(Field f) {
56         if (f.getName().equals("this$0")) hasThisDollarZero = true;
57     }
58     OpcodeStack stack = new OpcodeStack();
59     @Override JavaDoc
60          public void visit(Code obj) {
61         if (hasThisDollarZero) {
62         stack.resetForMethodEntry(this);
63         super.visit(obj);
64         }
65     }
66
67     private static String JavaDoc stripLastDollar(String JavaDoc s) {
68         int i = s.lastIndexOf('$');
69         if (i == -1) throw new IllegalArgumentException JavaDoc();
70         return s.substring(0,i);
71     }
72     @Override JavaDoc
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              // method is not inherited
81
return;
82          }
83          // method is inherited
84
String JavaDoc possibleTargetClass = getDottedClassName();
85          String JavaDoc 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 JavaDoc targetPackage = invokedMethod.getPackageName();
94                  String JavaDoc 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