001: /*
002: * FindBugs - Find Bugs in Java programs
003: * Copyright (C) 2006, University of Maryland
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: */
019:
020: package edu.umd.cs.findbugs.detect;
021:
022: import static org.apache.bcel.Constants.I2D;
023: import static org.apache.bcel.Constants.INVOKESTATIC;
024:
025: import org.objectweb.asm.FieldVisitor;
026: import org.objectweb.asm.MethodVisitor;
027: import org.objectweb.asm.Opcodes;
028:
029: import edu.umd.cs.findbugs.BugInstance;
030: import edu.umd.cs.findbugs.BugReporter;
031: import edu.umd.cs.findbugs.Detector2;
032: import edu.umd.cs.findbugs.MethodAnnotation;
033: import edu.umd.cs.findbugs.asm.AbstractFBMethodVisitor;
034: import edu.umd.cs.findbugs.asm.ClassNodeDetector;
035:
036: /**
037: * Sample detector, using ASM
038: *
039: * @author David Hovemeyer
040: */
041: public class TestASM extends ClassNodeDetector {
042:
043: public TestASM(BugReporter bugReporter) {
044: super (bugReporter);
045: }
046:
047: @Override
048: public MethodVisitor visitMethod(final int access,
049: final String name, final String desc,
050: final String signature, final String[] exceptions) {
051: if (Character.isUpperCase(name.charAt(0))) {
052: BugInstance bug0 = new BugInstance(this , "TESTING",
053: NORMAL_PRIORITY).addClass(this ).addMethod(
054: this .name, name, desc, access).addString(
055: "method should start with lower case character");
056: bugReporter.reportBug(bug0);
057: }
058: return new AbstractFBMethodVisitor() {
059: int prevOpcode;
060: int prevPC;
061:
062: @Override
063: public void visitInsn(int opcode) {
064: prevOpcode = opcode;
065: prevPC = getPC();
066: }
067:
068: @Override
069: public void visitMethodInsn(int opcode, String owner,
070: String invokedName, String invokedDesc) {
071: if (prevPC + 1 == getPC() && prevOpcode == I2D
072: && opcode == INVOKESTATIC
073: && owner.equals("java/lang/Math")
074: && invokedName.equals("ceil")
075: && invokedDesc.equals("(D)D"))
076: System.out.println(owner + "." + invokedName + ":"
077: + invokedDesc);
078: BugInstance bug0 = new BugInstance(
079: "ICAST_INT_CAST_TO_DOUBLE_PASSED_TO_CEIL",
080: NORMAL_PRIORITY);
081: MethodAnnotation methodAnnotation = MethodAnnotation
082: .fromForeignMethod(TestASM.this .name, name,
083: desc, access);
084: bug0.addClass(TestASM.this ).addMethod(methodAnnotation);
085: bugReporter.reportBug(bug0);
086: }
087:
088: };
089:
090: }
091:
092: @Override
093: public FieldVisitor visitField(int access, String name,
094: String desc, String signature, Object value) {
095: if ((access & Opcodes.ACC_STATIC) != 0
096: && (access & Opcodes.ACC_FINAL) != 0
097: && (access & Opcodes.ACC_PUBLIC) != 0
098: && !name.equals(name.toUpperCase()))
099: bugReporter.reportBug(new BugInstance(this , "TESTING",
100: Detector2.LOW_PRIORITY).addClass(this).addField(
101: this.name, name, desc, access));
102: return null;
103: }
104:
105: }
|