| 1 19 20 package edu.umd.cs.findbugs.detect; 21 22 import java.util.HashMap ; 23 import java.util.Map ; 24 25 import edu.umd.cs.findbugs.BugInstance; 26 import edu.umd.cs.findbugs.BugReporter; 27 import edu.umd.cs.findbugs.BytecodeScanningDetector; 28 import edu.umd.cs.findbugs.ba.ClassContext; 29 30 47 public class NumberConstructor extends BytecodeScanningDetector { 48 49 52 static class Info { 53 public final boolean isRealNumber; 54 public final String argName; 55 public final String constrArgs; 56 57 public Info(boolean isRealNumber, String argName, String constrArgs) { 58 this.isRealNumber = isRealNumber; 59 this.argName = argName; 60 this.constrArgs = constrArgs; 61 } 62 } 63 64 private static final Map <String , Info> boxClasses = new HashMap <String , Info>(); 65 static { 66 boxClasses.put("java/lang/Byte", new Info(false, "byte", "(B)V")); 67 boxClasses.put("java/lang/Character", new Info(false, "char", "(C)V")); 68 boxClasses.put("java/lang/Short", new Info(false, "short", "(S)V")); 69 boxClasses.put("java/lang/Integer", new Info(false, "int", "(I)V")); 70 boxClasses.put("java/lang/Long", new Info(false, "long", "(J)V")); 71 boxClasses.put("java/lang/Float", new Info(true, "float", "(F)V")); 72 boxClasses.put("java/lang/Double", new Info(true, "double", "(D)V")); 73 } 74 75 private final BugReporter bugReporter; 76 private boolean constantArgument; 77 78 82 public NumberConstructor(BugReporter bugReporter) { 83 this.bugReporter = bugReporter; 84 } 85 86 91 @Override  92 public void visitClassContext(ClassContext classContext) { 93 int majorVersion = classContext.getJavaClass().getMajor(); 94 if (majorVersion >= MAJOR_1_5) { 95 super.visitClassContext(classContext); 96 } 97 } 98 99 @Override  100 public void sawOpcode(int seen) { 101 if (seen == ICONST_0 || seen == LCONST_0 || 103 seen == ICONST_1 || seen == LCONST_1 || 104 seen == ICONST_2 || seen == ICONST_3 || 105 seen == ICONST_4 || seen == ICONST_5 || 106 seen == BIPUSH || seen == LDC) { 107 constantArgument = true; 108 return; 109 } 110 111 if (seen != INVOKESPECIAL) { 113 constantArgument = false; 114 return; 115 } 116 117 if (!"<init>".equals(getNameConstantOperand())) { 118 return; 119 } 120 String cls = getClassConstantOperand(); 121 Info info = boxClasses.get(cls); 122 if (info == null) { 123 return; 124 } 125 126 if (!info.constrArgs.equals(getSigConstantOperand())) { 127 return; 128 } 129 130 int prio; 131 String type; 132 if (info.isRealNumber) { 133 prio = LOW_PRIORITY; 134 type = "DM_FP_NUMBER_CTOR"; 135 } else { 136 prio = NORMAL_PRIORITY; 137 type = "DM_NUMBER_CTOR"; 138 } 139 140 cls = cls.substring(cls.lastIndexOf('/')+1); 141 bugReporter.reportBug(new BugInstance(this, type, prio) 142 .addClass(this) 143 .addMethod(this) 144 .addSourceLine(this) 145 .addString(cls+"("+info.argName+")") 146 .addString(cls+".valueOf("+info.argName+")")); 147 } 148 } 149 | Popular Tags |