Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * fb-contrib - Auxiliary detectors for Java programs
   * Copyright (C) 2005-2013 Dave Brosius
   *
   * This library is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 package com.mebigfatguy.fbcontrib.detect;
 
 import  org.apache.bcel.Repository;
 import  org.apache.bcel.classfile.Attribute;
 import  org.apache.bcel.classfile.Code;
 import  org.apache.bcel.classfile.Constant;
 import  org.apache.bcel.classfile.ConstantPool;
 import  org.apache.bcel.classfile.ConstantUtf8;
 import  org.apache.bcel.classfile.JavaClass;
 import  org.apache.bcel.classfile.Method;
 import  org.apache.bcel.classfile.Unknown;
 import  org.apache.bcel.generic.Type;
 
 
 import  edu.umd.cs.findbugs.BugInstance;
 import  edu.umd.cs.findbugs.BugReporter;
 import  edu.umd.cs.findbugs.BytecodeScanningDetector;
 import  edu.umd.cs.findbugs.OpcodeStack;
 import  edu.umd.cs.findbugs.ba.ClassContext;

looks for odd uses of the Assert class of the JUnit framework
 
 public class JUnitAssertionOddities extends BytecodeScanningDetector
 {
     private enum State {SAW_NOTHING, SAW_IF_ICMPNE, SAW_ICONST_1, SAW_GOTO, SAW_ICONST_0, SAW_EQUALS};
     
 	private static final String RUNTIME_VISIBLE_ANNOTATIONS = "RuntimeVisibleAnnotations";
 	private static final String TEST_ANNOTATION_SIGNATURE = "Lorg/junit/Test;";
 	private static final String OLD_ASSERT_CLASS = "junit/framework/Assert";
 	private static final String NEW_ASSERT_CLASS = "org/junit/Assert";
 	private static JavaClass testCaseClass;
 	private static JavaClass testAnnotationClass;
 	static {
 		try {
 			 = Repository.lookupClass("junit.framework.TestCase");
 		} catch (ClassNotFoundException cnfe) {
 			 = null;
 		}
 		try {
 			 = Repository.lookupClass("org.junit.Test");
 		} catch (ClassNotFoundException cnfe) {
 		}
 	}
 	private BugReporter bugReporter;
 	private OpcodeStack stack;
 	private boolean isTestCaseDerived;
 	private boolean isAnnotationCapable;
 	private State state;

constructs a JOA detector given the reporter to report bugs on

Parameters:
bugReporter the sync of bug reports
 
 	public JUnitAssertionOddities(BugReporter bugReporter) {
 		this. = bugReporter;
 	}

override the visitor to see if this class could be a test class

Parameters:
classContext the context object of the currently parsed class
 
 	public void visitClassContext(ClassContext classContext) {
 		try {
 			JavaClass cls = classContext.getJavaClass();
 			 = (( != null) && cls.instanceOf());
 			 = (cls.getMajor() >= 5) && ( != null);
 				 = new OpcodeStack();
 				super.visitClassContext(classContext);
 			}
 		} catch (ClassNotFoundException cnfe) {
 			.reportMissingClass(cnfe);
 		} finally {
 			 = null;
 		}
 	}
 
	public void visitCode(Code obj) {
		Method m = getMethod();
		boolean isTestMethod =  && m.getName().startsWith("test");
		if (!isTestMethod && ) {
			Attribute[] atts = m.getAttributes();
			for (Attribute att : atts) {
				ConstantPool cp = att.getConstantPool();
				Constant c = cp.getConstant(att.getNameIndex());
				if (c instanceof ConstantUtf8) {
					String name = ((ConstantUtf8) c).getBytes();
						if (att instanceof Unknown) {
							Unknown unAtt = (Unknown)att;
							byte[] bytes = unAtt.getBytes();
							int constantPoolIndex = bytes[3] & 0x000000FF;
							c = cp.getConstant(constantPoolIndex);
							if (c instanceof ConstantUtf8) {
								name = ((ConstantUtf8) c).getBytes();
									isTestMethod = true;
									break;
								}
							}
						}
					}
				}
			}
		}
		if (isTestMethod) {
			.resetForMethodEntry(this);
			super.visitCode(obj);
		}
	}
	public void sawOpcode(int seen) {
		String userValue = null;
		try {
			.mergeJumps(this);
			if (seen == INVOKESTATIC) {
				if (.equals(clsName) || .equals(clsName)) {
					String methodName = getNameConstantOperand();
					if ("assertEquals".equals(methodName)) {
						String signature = getSigConstantOperand();
						Type[] argTypes = Type.getArgumentTypes(signature);
						if (argTypes.length == 2) {
    						if (argTypes[0].equals(Type.STRING) && argTypes[1].equals(Type.STRING))
    							return;
    						if (.getStackDepth() >= 2) {
    							OpcodeStack.Item item1 = .getStackItem(1);
    							Object cons1 = item1.getConstant();
    							if ((cons1 != null) && (argTypes[argTypes.length-1].equals(Type.BOOLEAN)) && (argTypes[argTypes.length-2].equals(Type.BOOLEAN))) {
    								.reportBug(new BugInstance(this"JAO_JUNIT_ASSERTION_ODDITIES_BOOLEAN_ASSERT", NORMAL_PRIORITY)
    								   .addClass(this)
    								   .addMethod(this)
    								   .addSourceLine(this));
    								return;
    							}
    							OpcodeStack.Item item0 = .getStackItem(0);
    							if (item0.getConstant() != null) {
    								.reportBug(new BugInstance(this"JAO_JUNIT_ASSERTION_ODDITIES_ACTUAL_CONSTANT", NORMAL_PRIORITY)
    										   .addClass(this)
    										   .addMethod(this)
    										   .addSourceLine(this));
    								return;
    							}
    							if (argTypes[0].equals(Type.OBJECT) && argTypes[1].equals(Type.OBJECT)) {
    								if ("Ljava/lang/Double;".equals(item0.getSignature()) && "Ljava/lang/Double;".equals(item1.getSignature())) {
    									.reportBug(new BugInstance(this"JAO_JUNIT_ASSERTION_ODDITIES_INEXACT_DOUBLE", NORMAL_PRIORITY)
    									   .addClass(this)
    									   .addMethod(this)
    									   .addSourceLine(this));
    									return;
    								}
    							}
    						}
						}
else if ("assertNotNull".equals(methodName)) {
						if (.getStackDepth() > 0) {
							if ("valueOf".equals(.getStackItem(0).getUserValue())) {
								.reportBug(new BugInstance(this"JAO_JUNIT_ASSERTION_ODDITIES_IMPOSSIBLE_NULL", NORMAL_PRIORITY)
										   .addClass(this)
										   .addMethod(this)
										   .addSourceLine(this));
							}
						}
else if ("assertTrue".equals(methodName)) {
					    if (( == .) || ( == .)) {
					        .reportBug(new BugInstance(this"JAO_JUNIT_ASSERTION_ODDITIES_USE_ASSERT_EQUALS", NORMAL_PRIORITY)
					                        .addClass(this)
					                        .addMethod(this)
					                        .addSourceLine(this));
					    }
					}
else {
					String methodName = getNameConstantOperand();
					if (clsName.startsWith("java/lang/")
					&&  "valueOf".equals(methodName)
					&&  (sig.indexOf(")Ljava/lang/") >= 0)) {
						userValue = "valueOf";
					}
				}
else if (seen == ATHROW) {
			    if (.getStackDepth() > 0) {
			        OpcodeStack.Item item = .getStackItem(0);
    			    String throwClass = item.getSignature();
    			    if ("Ljava/lang/AssertionError;".equals(throwClass)) {
    			        .reportBug(new BugInstance(this"JAO_JUNIT_ASSERTION_ODDITIES_ASSERT_USED", NORMAL_PRIORITY)
    			                                .addClass(this)
    			                                .addMethod(this)
    			                                .addSourceLine(this));
    			    }
			    }
			}
			switch () {
			    if (seen == IF_ICMPNE)
			         = .;
			    else
			         = .;
			    break;
			    if (seen == ICONST_1)
			         = .;
			    else
			         = .;
			    break;
			    
			    if (seen == GOTO)
			         = .;
			    else
			         = .;
			            break;
			    
			case :
			    if (seen == ICONST_0)
			         = .;
		        else
		             = .;
		        break;
			    
			    default:
			         = .;
			    break;
			}
			if (seen == INVOKEVIRTUAL) {
			    String methodName = getNameConstantOperand();
			    String sig = getSigConstantOperand();
			    if ("equals".equals(methodName) && "(Ljava/lang/Object;)Z".equals(sig)) {
			         = .;
			    }
			}
finally {
			TernaryPatcher.pre(seen);
			.sawOpcode(thisseen);
			TernaryPatcher.post(seen);
			if ((userValue != null) && (.getStackDepth() > 0)) {
				OpcodeStack.Item item = .getStackItem(0);
				item.setUserValue(userValue);
			}
		}
	}
New to GrepCode? Check out our FAQ X