KickJava   Java API By Example, From Geeks To Geeks.

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


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
21 package edu.umd.cs.findbugs.detect;
22
23
24 import edu.umd.cs.findbugs.*;
25 import java.util.*;
26 import org.apache.bcel.classfile.*;
27
28 /**
29  * Find occurrences of Math using constants, where the result of the
30  * calculation can be determined statically. Replacing the math formula
31  * with the constant performs better, and sometimes is more accurate.
32  *
33  * @author Dave Brosius
34  */

35 public class UnnecessaryMath extends BytecodeScanningDetector implements StatelessDetector {
36     static final int SEEN_NOTHING = 0;
37     static final int SEEN_DCONST = 1;
38
39     private BugReporter bugReporter;
40     private int state = SEEN_NOTHING;
41     private double constValue;
42     
43     private static final Set<String JavaDoc> zeroMethods = new HashSet<String JavaDoc>()
44                                             {{ add("acos");
45                                                add("asin");
46                                                add("atan");
47                                                add("atan2");
48                                                add("cbrt");
49                                                add("cos");
50                                                add("cosh");
51                                                add("exp");
52                                                add("expm1");
53                                                add("log");
54                                                add("log10");
55                                                add("pow");
56                                                add("sin");
57                                                add("sinh");
58                                                add("sqrt");
59                                                add("tan");
60                                                add("tanh");
61                                                add("toDegrees");
62                                                add("toRadians");
63                                             }};
64     private static final Set<String JavaDoc> oneMethods = new HashSet<String JavaDoc>()
65                                             {{ add("acos");
66                                                add("asin");
67                                                add("atan");
68                                                add("cbrt");
69                                                add("exp");
70                                                add("log");
71                                                add("log10");
72                                                add("pow");
73                                                add("sqrt");
74                                                add("toDegrees");
75                                             }};
76     private static final Set<String JavaDoc> anyMethods = new HashSet<String JavaDoc>()
77                                             {{ add("abs");
78                                                add("ceil");
79                                                add("floor");
80                                                add("rint");
81                                                add("round");
82                                             }};
83
84     public UnnecessaryMath(BugReporter bugReporter) {
85         this.bugReporter = bugReporter;
86     }
87     
88
89
90     @Override JavaDoc
91          public void visit(Code obj) {
92         // Don't complain about unnecessary math calls in class initializers,
93
// since they may be there to improve readability.
94
if (getMethod().getName().equals("<clinit>"))
95             return;
96         
97         state = SEEN_NOTHING;
98         super.visit(obj);
99     }
100
101     @Override JavaDoc
102          public void sawOpcode(int seen) {
103         if (state == SEEN_NOTHING) {
104             if ((seen == DCONST_0) || (seen == DCONST_1)) {
105                 constValue = (double) (seen - DCONST_0);
106                 state = SEEN_DCONST;
107             }
108             else if ((seen == LDC2_W) || (seen == LDC_W)) {
109                 state = SEEN_DCONST;
110                 Constant c = this.getConstantRefOperand();
111                 if (c instanceof ConstantDouble)
112                     constValue = ((ConstantDouble)c).getBytes();
113                 else if (c instanceof ConstantFloat)
114                     constValue = ((ConstantFloat)c).getBytes();
115                 else if (c instanceof ConstantLong)
116                     constValue = ((ConstantLong)c).getBytes();
117                 else
118                     state = SEEN_NOTHING;
119             }
120         } else if (state == SEEN_DCONST) {
121             if (seen == INVOKESTATIC) {
122                 state = SEEN_NOTHING;
123                 if (getDottedClassConstantOperand().equals("java.lang.Math")) {
124                     String JavaDoc methodName = getNameConstantOperand();
125                     
126                     if (((constValue == 0.0) && zeroMethods.contains(methodName))
127                     || ((constValue == 1.0) && oneMethods.contains(methodName))
128                     || (anyMethods.contains(methodName))) {
129                         bugReporter.reportBug(new BugInstance("UM_UNNECESSARY_MATH", LOW_PRIORITY)
130                                                 .addClassAndMethod(this)
131                                                 .addSourceLine(this));
132                     }
133                 }
134             }
135             state = SEEN_NOTHING;
136         }
137     }
138 }
139
140 // vim:ts=4
141
Popular Tags