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 java.util.Set;
 
 import  org.apache.bcel.classfile.Method;
 
 
 import  edu.umd.cs.findbugs.BugInstance;
 import  edu.umd.cs.findbugs.BugReporter;
 import  edu.umd.cs.findbugs.BytecodeScanningDetector;


Looks for inefficient comparison of Date objects using two comparisons when one would do.
 
 public class DateComparison extends BytecodeScanningDetector
 {
 	enum State {SAW_NOTHING, SAW_LOAD1_1, SAW_LOAD1_2, SAW_CMP1, SAW_IFNE, SAW_LOAD2_1, SAW_LOAD2_2, SAW_CMP2}
 	
 	private static final Set<StringdateClasses = new HashSet<String>();
 	static {
 		.add("java.util.Date");
 		.add("java.sql.Date");
 		.add("java.sql.Timestamp");
 	}
 	
     private final BugReporter bugReporter;
     private State state;
     private int register1_1;
     private int register1_2;
     private int register2_1;
     private int register2_2;

    
constructs a DDC detector given the reporter to report bugs on

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

overrides the visitor to reset the registers

Parameters:
obj the method of the currently parsed method
 
 	public void visit(Method obj) {
          = .;
          = -1;
          = -1;
          = -1;
          = -1;
         super.visit(obj);
     }

overrides the visitor to look for double date compares using the same registers

Parameters:
seen the current opcode parsed.
 
 	public void sawOpcode(int seen) {
         switch () {
         	case :
         		if ((seen == ALOAD) || ((seen >= ALOAD_0) && (seen <= ALOAD_3))) {
         			 = RegisterUtils.getALoadReg(thisseen);
         			 = .;
                 }
         	break;
         	
         	case :
         		if ((seen == ALOAD) || ((seen >= ALOAD_0) && (seen <= ALOAD_3)))
         			 = RegisterUtils.getALoadReg(thisseen);
         			
         		if ( > -1)
         			 = .;
         		else
         			 = .;
        	break;
        	
        	case :
        		if (seen == INVOKEVIRTUAL) {
        			String cls = getDottedClassConstantOperand();
        			if (.contains(cls)) {
        				String methodName = getNameConstantOperand();
        				if ("equals".equals(methodName)
        				||  "after".equals(methodName)
        				||  "before".equals(methodName)) {
        					 = .;
        				}
        			}
        		}
        		if ( != .)
        			 = .;
        	break;
        	
        	case :
        		if (seen == IFNE)
        			 = .;
        		else
        			 = .;
        	break;
			case :
				if ((seen == ALOAD) || ((seen >= ALOAD_0) && (seen <= ALOAD_3)))
	    			 = RegisterUtils.getALoadReg(thisseen);
	    			
	    		if ( > -1)
	    			 = .;
	    		else
	    			 = .;
	    	break;
				if ((seen == ALOAD) || ((seen >= ALOAD_0) && (seen <= ALOAD_3)))
	    			 = RegisterUtils.getALoadReg(thisseen);
	    			
	    		if (( > -1) 
	    		&&  ( (( == ) && ( == ))
	    		    ||(( == ) && ( == ))))
	    				 = .;
	    		else
	    			 = .;
	    	break;
	    	
	    	case :
        		if (seen == INVOKEVIRTUAL) {
        			String cls = getDottedClassConstantOperand();
        			if (.contains(cls)) {
        				String methodName = getNameConstantOperand();
        				if ("equals".equals(methodName)
        				||  "after".equals(methodName)
        				||  "before".equals(methodName)) {
        					 = .;
        				}
        			}
        		}
        		if ( != .)
        			 = .;
	    	break;
	    	
	    	case :
	    		if (seen == IFEQ) {
	    			.reportBug(new BugInstance("DDC_DOUBLE_DATE_COMPARISON", NORMAL_PRIORITY)
								.addClassAndMethod(this)
								.addSourceLine(this));
	    		}
	    		 = .;
	    	break;
        }
    }
New to GrepCode? Check out our FAQ X