Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * fb-contrib - Auxiliary detectors for Java programs
   * Copyright (C) 2005-2015 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.Map;
 
 
 
looks for methods that perform arithmetic operations on values representing time where the time unit is incompatible, ie adding a millisecond value to a nanosecond value.
 
 public class ConflictingTimeUnits extends BytecodeScanningDetector {
 
 	private enum Units { NANOS, MICROS, MILLIS, SECONDS, MINUTES, HOURS, DAYS, CALLER };
 	
 	private static Map<StringUnitsTIME_UNIT_GENERATING_METHODS = new HashMap<StringUnits>();
 	static {
 		.put("java/lang/System.currentTimeMillis()J".);
 		.put("java/lang/System.nanoTime()J".);
 		.put("java/sql/Timestamp.getTime()J".);
 		.put("java/sql/Timestamp.getNanos()I".);
 		.put("java/util/Date.getTime()J".);
 		.put("java/util/concurrent/TimeUnit.toNanos(J)J".);
 		.put("java/util/concurrent/TimeUnit.toMicros(J)J".);
 		.put("java/util/concurrent/TimeUnit.toSeconds(J)J".);
 		.put("java/util/concurrent/TimeUnit.toMinutes(J)J".);
 		.put("java/util/concurrent/TimeUnit.toHours(J)J".);
 		.put("java/util/concurrent/TimeUnit.toDays(J)J".);
 		.put("java/util/concurrent/TimeUnit.excessNanos(JJ)I".);
 		.put("java/util/concurrent/TimeUnit.convert(JLjava/util/concurrent/TimeUnit;)J".);
 		.put("edu/emory/matchcs/backport/java/util/concurrent/TimeUnit.toNanos(J)J".);
 		.put("edu/emory/matchcs/backport/java/util/concurrent/TimeUnit.toMicros(J)J".);
 		.put("edu/emory/matchcs/backport/java/util/concurrent/TimeUnit.toSeconds(J)J".);
 		.put("edu/emory/matchcs/backport/java/util/concurrent/TimeUnit.toMinutes(J)J".);
 		.put("edu/emory/matchcs/backport/java/util/concurrent/TimeUnit.toHours(J)J".);
 		.put("edu/emory/matchcs/backport/java/util/concurrent/TimeUnit.toDays(J)J".);
 		.put("edu/emory/matchcs/backport/java/util/concurrent/TimeUnit.excessNanos(JJ)I".);
 		.put("edu/emory/matchcs/backport/java/util/concurrent/TimeUnit.convert(JLjava/util/concurrent/TimeUnit;)J".);
 		.put("org/joda/time/base/BaseDuration.getMillis()J".);
 		.put("org/joda/time/base/BaseInterval.getEndMillis()J".);
 		.put("org/joda/time/base/BaseInterval.getStartMillis()J".);
 	}
 	
 	private static Map<StringUnitsTIMEUNIT_TO_UNITS = new HashMap<StringUnits>();
 	static {
 		.put("NANOSECONDS".);
 		.put("MICROSECONDS".);
 		.put("MILLISECONDS".);
 	}
 	
 	private OpcodeStack stack;

constructs a CTU detector given the reporter to report bugs on

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

overrides the visitor to reset the stack

Parameters:
classContext the context object of the currently parsed class
 
	public void visitClassContext(ClassContext classContext) {
		try {
			 = new OpcodeStack();
			super.visitClassContext(classContext);
finally {
			 = null;
		}
	}

overrides the visitor to resets the stack for this method.

Parameters:
obj the context object for the currently parsed code block
	public void visitCode(Code obj) {
		super.visitCode(obj);
	}

overrides the visitor to look for operations on two time unit values that are conflicting
	public void sawOpcode(int seen) {
		Units unit = null;
		try {
			switch (seen) {
					unit = .get(methodCall);
					if (unit == .) {
						int offset = Type.getArgumentTypes(getSigConstantOperand()).length;
						if (.getStackDepth() > offset) {
							unit = (Unitsitem.getUserValue();
else {
							unit = null;
						}
					}
				break;
				case :
					if ("java/util/concurrent/TimeUnit".equals(clsName
					||  "edu/emory/matchcs/backport/java/util/concurrent/TimeUnit".equals(clsName)) {
					}
				break;
				case :
				case :
					if (.getStackDepth() > 0) {
						unit = (Unitsitem.getUserValue();
					}
				break;
				case :
				case :
				case :
				case :
				case :
				case :
				case :
				case :
				case :
				case :
					if (.getStackDepth() > 1) {
						Units u1 = (Unitsarg1.getUserValue();
						Units u2 = (Unitsarg2.getUserValue();
						if ((u1 != null) && (u2 != null) && (u1 != u2)) {
										.addClass(this)
										.addMethod(this)
						}
					}
				break;
				default:
				break;
			}
finally {
			.sawOpcode(thisseen);
			if ((unit != null) && (.getStackDepth() > 0)) {
				item.setUserValue(unit);
			}
		}
	}
New to GrepCode? Check out our FAQ X