KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * FindBugs - Find bugs in Java programs
3  * Copyright (C) 2005 Dave Brosius <dbrosius@users.sourceforge.net>
4  * Copyright (C) 2005 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 package edu.umd.cs.findbugs.detect;
21
22
23 import edu.umd.cs.findbugs.*;
24 import java.util.regex.Pattern JavaDoc;
25 import org.apache.bcel.classfile.Code;
26
27 /* Look for sequences of the form:
28  * ICONST_1
29  ANEWARRAY int[]
30  DUP
31  ICONST_0
32  ALOAD 1: a
33  AASTORE
34  INVOKESTATIC Arrays.asList(Object[]) : List
35  */

36
37 public class VarArgsProblems extends BytecodeScanningDetector implements
38         StatelessDetector {
39
40     private BugReporter bugReporter;
41
42     private int state;
43
44     public VarArgsProblems(BugReporter bugReporter) {
45         this.bugReporter = bugReporter;
46     }
47
48
49
50     @Override JavaDoc
51          public void visitCode(Code obj) {
52         state = SEEN_NOTHING;
53         super.visitCode(obj);
54     }
55
56     public static final int SEEN_NOTHING = 0;
57
58     public static final int SEEN_ICONST_1 = 1;
59
60     public static final int SEEN_ANEWARRAY = 2;
61
62     public static final int SEEN_DUP = 3;
63
64     public static final int SEEN_ICONST_0 = 4;
65
66     public static final int SEEN_ALOAD = 5;
67
68     public static final int SEEN_AASTORE = 6;
69
70     public static final int SEEN_GOTO = 7;
71
72     Pattern JavaDoc primitiveArray = Pattern.compile("\\[[IJDFSCB]");
73     String JavaDoc primitiveArraySig;
74     @Override JavaDoc
75          public void sawOpcode( int seen) {
76         // System.out.println("State:" + state);
77
if (seen == GOTO && getBranchOffset() == 4) {
78             state = SEEN_GOTO;
79         } else
80             switch (state) {
81             case SEEN_NOTHING:
82                 if ((seen == ICONST_1))
83                     state = SEEN_ICONST_1;
84                 break;
85
86             case SEEN_ICONST_1:
87                 if (seen == ANEWARRAY && primitiveArray.matcher(getClassConstantOperand()).matches()) {
88                     // System.out.println("Allocation of array of type " + getClassConstantOperand());
89
primitiveArraySig = getClassConstantOperand();
90                     state = SEEN_ANEWARRAY;
91                 }
92                 else
93                     state = SEEN_NOTHING;
94                 break;
95
96             case SEEN_ANEWARRAY:
97                 if (seen == DUP)
98                     state = SEEN_DUP;
99                 else
100                     state = SEEN_NOTHING;
101                 break;
102             case SEEN_DUP:
103                 if (seen == ICONST_0)
104                     state = SEEN_ICONST_0;
105                 else
106                     state = SEEN_NOTHING;
107                 break;
108             case SEEN_ICONST_0:
109                 if (((seen >= ALOAD_0) && (seen < ALOAD_3)) || (seen == ALOAD))
110                     state = SEEN_ALOAD;
111                 else
112                     state = SEEN_NOTHING;
113                 break;
114
115             case SEEN_ALOAD:
116                 if (seen == AASTORE)
117                     state = SEEN_AASTORE;
118                 else
119                     state = SEEN_NOTHING;
120                 break;
121
122             case SEEN_AASTORE:
123                 if (seen == INVOKESTATIC || seen == INVOKEINTERFACE
124                         || seen == INVOKESPECIAL || seen == INVOKEVIRTUAL) {
125 // System.out.println(getClassConstantOperand());
126
// System.out.println(getNameConstantOperand());
127
// System.out.println(getSigConstantOperand());
128
if (getSigConstantOperand().indexOf("Ljava/lang/Object;)") == -1) break;
129                     int priority = NORMAL_PRIORITY;
130                     if (getNameConstantOperand().equals("asList")
131                             && getClassConstantOperand().equals("java/util/Arrays"))
132                             priority = HIGH_PRIORITY;
133                     bugReporter.reportBug( new BugInstance( this, "VA_PRIMITIVE_ARRAY_PASSED_TO_OBJECT_VARARG", priority)
134                             .addClassAndMethod(this)
135                             .addType(primitiveArraySig)
136                             .addCalledMethod(this)
137                             .addSourceLine(this));
138                 }
139                 state = SEEN_NOTHING;
140                 break;
141
142             case SEEN_GOTO:
143                 state = SEEN_NOTHING;
144                 break;
145             default:
146                 throw new IllegalStateException JavaDoc("State " + state
147                         + " not expected");
148
149             }
150     }
151 }
152
Popular Tags