KickJava   Java API By Example, From Geeks To Geeks.

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


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

20
21 package edu.umd.cs.findbugs.detect;
22
23
24 import edu.umd.cs.findbugs.*;
25 import edu.umd.cs.findbugs.ba.AnalysisContext;
26 import edu.umd.cs.findbugs.ba.ClassContext;
27 import org.apache.bcel.Repository;
28 import org.apache.bcel.classfile.*;
29
30 /**
31  * Find occurrences of collection.toArray( new Foo[0] );
32  * This causes another memory allocation through reflection
33  * Much better to do collection.toArray( new Foo[collection.size()] );
34  *
35  * @author Dave Brosius
36  */

37 public class InefficientToArray extends BytecodeScanningDetector implements StatelessDetector {
38     private static final boolean DEBUG = SystemProperties.getBoolean("ita.debug");
39
40     static final int SEEN_NOTHING = 0;
41     static final int SEEN_ICONST_0 = 1;
42     static final int SEEN_ANEWARRAY = 2;
43
44     private final static JavaClass collectionClass;
45
46     private BugReporter bugReporter;
47     private int state = SEEN_NOTHING;
48
49     static {
50         JavaClass tmp = null;
51         try {
52             tmp = AnalysisContext.lookupSystemClass("java.util.Collection");
53         } catch (ClassNotFoundException JavaDoc cnfe) {
54             AnalysisContext.reportMissingClass(cnfe);
55         }
56         collectionClass = tmp;
57     }
58
59     public InefficientToArray(BugReporter bugReporter) {
60         this.bugReporter = bugReporter;
61     }
62
63
64
65     @Override JavaDoc
66          public void visitClassContext(ClassContext classContext) {
67         if (collectionClass != null)
68             classContext.getJavaClass().accept(this);
69     }
70     
71     @Override JavaDoc
72          public void visit(Method obj) {
73         if (DEBUG)
74             System.out.println("------------------- Analyzing " + obj.getName() + " ----------------");
75         state = SEEN_NOTHING;
76         super.visit(obj);
77     }
78
79     @Override JavaDoc
80          public void sawOpcode(int seen) {
81         if (DEBUG) System.out.println("State: " + state + " Opcode: " + OPCODE_NAMES[seen]);
82
83         switch (state) {
84         case SEEN_NOTHING:
85             if (seen == ICONST_0)
86                 state = SEEN_ICONST_0;
87             break;
88
89         case SEEN_ICONST_0:
90             if (seen == ANEWARRAY) {
91                 state = SEEN_ANEWARRAY;
92             } else
93                 state = SEEN_NOTHING;
94             break;
95
96         case SEEN_ANEWARRAY:
97             if (((seen == INVOKEVIRTUAL) || (seen == INVOKEINTERFACE))
98                     && (getNameConstantOperand().equals("toArray"))
99                     && (getSigConstantOperand().equals("([Ljava/lang/Object;)[Ljava/lang/Object;"))) {
100                 try {
101                     String JavaDoc clsName = getDottedClassConstantOperand();
102                     JavaClass cls = Repository.lookupClass(clsName);
103                     if (cls.implementationOf(collectionClass))
104                         bugReporter.reportBug(new BugInstance(this, "ITA_INEFFICIENT_TO_ARRAY", LOW_PRIORITY)
105                                 .addClassAndMethod(this)
106                                 .addSourceLine(this));
107
108                 } catch (ClassNotFoundException JavaDoc cnfe) {
109                     bugReporter.reportMissingClass(cnfe);
110                 }
111             }
112             state = SEEN_NOTHING;
113             break;
114
115         default:
116             state = SEEN_NOTHING;
117             break;
118         }
119     }
120 }
121
122 // vim:ts=4
123
Popular Tags