Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package com.mebigfatguy.fbcontrib.detect;
  
  import java.util.Arrays;
  import java.util.BitSet;
  import java.util.HashSet;
  import java.util.Iterator;
  import java.util.List;
 import java.util.Set;
 
 
 
looks for two or more try catch blocks that are consecutive and catch the same kind of exception, and throw the same exception always. These blocks can be coalesced into one.
 
 
 public class StackedTryBlocks extends BytecodeScanningDetector {
 
     private static JavaClass THROWABLE_CLASS;
 
     static {
         try {
              = Repository.lookupClass("java/lang/Throwable");
         } catch (ClassNotFoundException cnfe) {
              = null;
         }
     }
 	private final BugReporter bugReporter;
 	private List<TryBlockblocks;
 	private List<TryBlockinBlocks;
 	private OpcodeStack stack;
 
 	public StackedTryBlocks(BugReporter bugReporter) {
 		this. = bugReporter;
 	}
 
 	public void visitClassContext(ClassContext classContext) {
 		try {
 		    if ( != null) {
     			 = new OpcodeStack();
     			super.visitClassContext(classContext);
 		    }
 		} finally {
 			 = null;
 		}
 	}
 
 	public void visitCode(Code obj) {
 
 		try {
 			XMethod xMethod = getXMethod();
 			if (xMethod != null) {
     			String[] tes = xMethod.getThrownExceptions();
     			Set<StringthrownExceptions = new HashSet<String>(Arrays.<StringasList((tes == null) ? new String[0] : tes));
     
     			 = new ArrayList<TryBlock>();
     			 = new ArrayList<TryBlock>();
     			 = new ArrayList<Integer>();
     
     			CodeException[] ces = obj.getExceptionTable();
     			for (CodeException ce : ces) {
     				TryBlock tb = new TryBlock(ce);
     				int existingBlock = .indexOf(tb);
     				if (existingBlock >= 0) {
     					tb = .get(existingBlock);
     					tb.addCatchType(ce);
     				} else {
     					.add(tb);
     				}
     			}
     
     			Iterator<TryBlockit = .iterator();
     			while (it.hasNext()) {
    				TryBlock block = it.next();
    				if (block.hasMultipleHandlers() || block.isFinally()
    						|| block.catchIsThrown(getConstantPool(), thrownExceptions)) {
    					it.remove();
    				}
    			}
    
    			if (.size() > 1) {
    				super.visitCode(obj);
    
    				if (.size() > 1) {
                        Collections.sort();
    
                        TryBlock firstBlock = .get(0);
    					for (int i = 1; i < .size(); i++) {
    						TryBlock secondBlock = .get(i);
    
    						if (!blocksSplitAcrossTransitions(firstBlocksecondBlock)) {
        						if ((firstBlock.getCatchType() == secondBlock.getCatchType())
                                        && (firstBlock.getThrowSignature().equals(secondBlock.getThrowSignature())
                                        && (firstBlock.getMessage().equals(secondBlock.getMessage())
        								&& (firstBlock.getExceptionSignature().equals(secondBlock.getExceptionSignature()))))) {
        									.addClass(this).addMethod(this)
        									.addSourceLineRange(thisfirstBlock.getStartPC(), firstBlock.getEndHandlerPC())
        									.addSourceLineRange(thissecondBlock.getStartPC(), secondBlock.getEndHandlerPC()));
    
        						}
    						}
    
    						firstBlock = secondBlock;
    					}
    				}
    			}
			}
finally {
			 = null;
			 = null;
		}
	}
	public void sawOpcode(int seen) {
	    String message = null;
		try {
	        .precomputation(this);
	        
		    if ((seen == ) || (seen == )) {
		        for (int offset : getSwitchOffsets()) {
		            .add(Integer.valueOf(offset));
		        }
		    } else if (isBranch(seen)) {
		        // throw out try blocks in loops, this could cause false negatives
		        // with two try/catches in one loop, but more unlikely
		        if (getBranchOffset() < 0) {
		            Iterator<TryBlockit = .iterator();
		            int target = getBranchTarget();
		            while (it.hasNext()) {
		                TryBlock block = it.next();
		                if (block.getStartPC() >= target) {
		                    it.remove();
		                }
		            }
		        }
		    }
			int pc = getPC();
			if (block != null) {
				.add(block);
			}
			if (.size() > 0) {
				TryBlock innerBlock = .get(.size() - 1);
				int nextPC = getNextPC();
				if (innerBlock.atHandlerPC(nextPC)) {
					if ((seen == ) || (seen == )) {
else {
						.remove(innerBlock);
						.remove(innerBlock);
					}
else if (innerBlock.atHandlerPC(pc)) {
else if (innerBlock.atEndHandlerPC(pc)) {
				}
				if (innerBlock.inCatch()) {
					if (((seen >= .) && ((seen <= .)))
							|| ((seen >= .) && (seen <= .)) || (seen == )) {
						.remove(innerBlock);
else if (seen == ) {
						if (.getStackDepth() > 0) {
							XMethod xm = item.getReturnValueOf();
							if (xm != null) {
							    innerBlock.setThrowSignature(xm.getSignature());
							}
                            innerBlock.setExceptionSignature(item.getSignature());
                            innerBlock.setMessage((Stringitem.getUserValue());
else {
						}
else if ((seen == ) && ..equals(getNameConstantOperand())) {
					    String cls = getClassConstantOperand();
					    JavaClass exCls = Repository.lookupClass(cls);
					    if (exCls.instanceOf()) {
					        String signature = getSigConstantOperand();
					        Type[] types = Type.getArgumentTypes(signature);
					        if (types.length > 0) {
					            if ("Ljava/lang/String;".equals(types[0].getSignature())) {
    					            if (.getStackDepth() >= types.length) {
    					                OpcodeStack.Item item = .getStackItem(types.length - 1);
    					                message = (String)item.getConstant();
    					                if (message == null) {
    					                    message = "____UNKNOWN____" + System.identityHashCode(item);
    					                }
    					            }
					            }
					        } else {
					            message = "";
					        }
					    }
					}
				}
			}
catch (ClassNotFoundException cnfe) {
finally {
			.sawOpcode(thisseen);
			if ((message != null) && (.getStackDepth() > 0)) {
			    OpcodeStack.Item item = .getStackItem(0);
			    item.setUserValue(message);
			}
		}
	}
	private TryBlock findBlockWithStart(int pc) {
		for (TryBlock block : ) {
			if (block.atStartPC(pc)) {
				return block;
			}
		}
		return null;
	}
	private boolean blocksSplitAcrossTransitions(TryBlock firstBlockTryBlock secondBlock) {
	    if (!.isEmpty()) {
    	    Iterator<Integerit = .iterator();
    	    while (it.hasNext()) {
    	        Integer transitionPoint = it.next();
    	        if (transitionPoint.intValue() < firstBlock.handlerPC) {
    	            it.remove();
    	        } else {
    	            return transitionPoint.intValue() < secondBlock.handlerPC;
    	        }
    	    }
	    }
	    return false;
	}
	static class TryBlock {
		enum State {
			BEFORE, IN_TRY, IN_CATCH, AFTER
		};
		int startPC;
		int endPC;
			 = ce.getEndPC();
			 = new BitSet();
		}
		}
		void setState(State executionState) {
			 = executionState;
		}
		boolean inCatch() {
			return  == .;
		}
		boolean hasMultipleHandlers() {
			int bit = .nextSetBit(0);
			return .nextSetBit(bit + 1) >= 0;
		}
		boolean isFinally() {
			return .get(0);
		}
		boolean catchIsThrown(ConstantPool poolSet<StringthrownExceptions) {
			if (thrownExceptions.size() > 0) {
				int exIndex = .nextSetBit(0);
				String exName = ((ConstantClasspool.getConstant(exIndex)).getBytes(pool);
				return thrownExceptions.contains(exName);
			}
			return false;
		}
		void setEndHandlerPC(int end) {
			 = end;
		}
		     = sig;
		}
			 = sig;
		}
		void setMessage(String m) {
		     = m;
		}
		    return ( == null) ? String.valueOf(System.identityHashCode(this)) : ;
		}
			return ( == null) ? String.valueOf(System.identityHashCode(this)) : ;
		}
            return ( == null) ? String.valueOf(System.identityHashCode(this)) : ;
		}
		int getStartPC() {
			return ;
		}
			return ;
		}
		boolean atStartPC(int pc) {
			return  == pc;
		}
		boolean atHandlerPC(int pc) {
			return  == pc;
		}
		boolean atEndHandlerPC(int pc) {
			return ( >= 0) && ( == pc);
		}
		int getCatchType() {
		}
		public int hashCode() {
			return  ^ ;
		}
		public boolean equals(Object o) {
			if (o instanceof TryBlock) {
				TryBlock that = (TryBlocko;
				return ( == that.startPC) && ( == that.endPC);
			}
			return false;
		}
		public String toString() {
			return ToString.build(this);
		}
	}
New to GrepCode? Check out our FAQ X