⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 classcontext.java

📁 A static analysis tool to find bugs in Java programs
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/* * Bytecode Analysis Framework * Copyright (C) 2003-2005 University of Maryland *  * 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 edu.umd.cs.findbugs.ba;import java.util.ArrayList;import java.util.Arrays;import java.util.BitSet;import java.util.Collection;import java.util.Collections;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.LinkedList;import java.util.List;import java.util.Map;import java.util.Set;import java.util.TreeSet;import org.apache.bcel.Constants;import org.apache.bcel.classfile.Code;import org.apache.bcel.classfile.JavaClass;import org.apache.bcel.classfile.LineNumber;import org.apache.bcel.classfile.LineNumberTable;import org.apache.bcel.classfile.Method;import org.apache.bcel.generic.ClassGen;import org.apache.bcel.generic.ClassGenException;import org.apache.bcel.generic.ConstantPoolGen;import org.apache.bcel.generic.FieldInstruction;import org.apache.bcel.generic.GETSTATIC;import org.apache.bcel.generic.IFNE;import org.apache.bcel.generic.INVOKESTATIC;import org.apache.bcel.generic.Instruction;import org.apache.bcel.generic.InstructionHandle;import org.apache.bcel.generic.InstructionList;import org.apache.bcel.generic.InvokeInstruction;import org.apache.bcel.generic.MethodGen;import edu.umd.cs.findbugs.SystemProperties;import edu.umd.cs.findbugs.TigerSubstitutes;import edu.umd.cs.findbugs.annotations.CheckForNull;import edu.umd.cs.findbugs.annotations.NonNull;import edu.umd.cs.findbugs.annotations.Nullable;import edu.umd.cs.findbugs.ba.ca.CallListAnalysis;import edu.umd.cs.findbugs.ba.ca.CallListDataflow;import edu.umd.cs.findbugs.ba.constant.ConstantAnalysis;import edu.umd.cs.findbugs.ba.constant.ConstantDataflow;import edu.umd.cs.findbugs.ba.deref.UnconditionalValueDerefAnalysis;import edu.umd.cs.findbugs.ba.deref.UnconditionalValueDerefDataflow;import edu.umd.cs.findbugs.ba.deref.UnconditionalValueDerefSet;import edu.umd.cs.findbugs.ba.heap.LoadAnalysis;import edu.umd.cs.findbugs.ba.heap.LoadDataflow;import edu.umd.cs.findbugs.ba.heap.StoreAnalysis;import edu.umd.cs.findbugs.ba.heap.StoreDataflow;import edu.umd.cs.findbugs.ba.npe.DerefFinder;import edu.umd.cs.findbugs.ba.npe.IsNullValueAnalysis;import edu.umd.cs.findbugs.ba.npe.IsNullValueDataflow;import edu.umd.cs.findbugs.ba.npe.ReturnPathTypeAnalysis;import edu.umd.cs.findbugs.ba.npe.ReturnPathTypeDataflow;import edu.umd.cs.findbugs.ba.npe.UsagesRequiringNonNullValues;import edu.umd.cs.findbugs.ba.npe2.DefinitelyNullSetAnalysis;import edu.umd.cs.findbugs.ba.npe2.DefinitelyNullSetDataflow;import edu.umd.cs.findbugs.ba.type.ExceptionSetFactory;import edu.umd.cs.findbugs.ba.type.TypeAnalysis;import edu.umd.cs.findbugs.ba.type.TypeDataflow;import edu.umd.cs.findbugs.ba.vna.LoadedFieldSet;import edu.umd.cs.findbugs.ba.vna.MergeTree;import edu.umd.cs.findbugs.ba.vna.ValueNumberAnalysis;import edu.umd.cs.findbugs.ba.vna.ValueNumberDataflow;import edu.umd.cs.findbugs.util.MapCache;import edu.umd.cs.findbugs.util.TopologicalSort;import edu.umd.cs.findbugs.util.TopologicalSort.OutEdges;/** * A ClassContext caches all of the auxiliary objects used to analyze * the methods of a class.  That way, these objects don't need to * be created over and over again. * * @author David Hovemeyer */public class ClassContext {	public static final boolean DEBUG = SystemProperties.getBoolean("classContext.debug");	private static final int PRUNED_INFEASIBLE_EXCEPTIONS = 1;	private static final int PRUNED_UNCONDITIONAL_THROWERS = 2;	private static final int REFINED = 4;	private static final boolean TIME_ANALYSES = SystemProperties.getBoolean("classContext.timeAnalyses");	private static final boolean DEBUG_CFG = SystemProperties.getBoolean("classContext.debugCFG");	private static final boolean DUMP_DATAFLOW_ANALYSIS = SystemProperties.getBoolean("dataflow.dump");	/* ----------------------------------------------------------------------	 * Helper classes	 * ---------------------------------------------------------------------- */	/**	 * Unpacked code for a method.	 * Contains set of all opcodes in the method, as well as a map	 * of bytecode offsets to opcodes.	 */	private static class UnpackedCode {		private BitSet bytecodeSet;		private short[] offsetToBytecodeMap;		public UnpackedCode(BitSet bytecodeSet, short[] offsetToBytecodeMap) {			this.bytecodeSet = bytecodeSet;			this.offsetToBytecodeMap = offsetToBytecodeMap;		}		/**		 * @return Returns the bytecodeSet.		 */		public BitSet getBytecodeSet() {			return bytecodeSet;		}		/**		 * @return Returns the offsetToBytecodeMap.		 */		public short[] getOffsetToBytecodeMap() {			return offsetToBytecodeMap;		}	}	private static int depth;	private static void indent() {		for (int i = 0; i < depth; ++i) System.out.print("  ");	}	/**	 * An AnalysisResult stores the result of requesting an analysis	 * from an AnalysisFactory.  It can represent a successful outcome	 * (where the Analysis object can be returned), or an unsuccessful	 * outcome (where an exception was thrown trying to create the	 * analysis).  For unsuccessful outcomes, we rethrow the original	 * exception rather than making another attempt to create the analysis	 * (since if it fails once, it will never succeed). 	 */	private static class AnalysisResult<Analysis> {		private boolean analysisSetExplicitly;		private Analysis analysis;		private AnalysisException analysisException;		private CFGBuilderException cfgBuilderException;		private DataflowAnalysisException dataflowAnalysisException;		public Analysis getAnalysis() throws CFGBuilderException, DataflowAnalysisException {			if (analysisSetExplicitly)				return analysis;			if (dataflowAnalysisException != null)				throw dataflowAnalysisException;			if (analysisException != null)				throw analysisException;			if (cfgBuilderException != null)				throw cfgBuilderException;			throw new IllegalStateException();		}		/**		 * Record a successful outcome, where the analysis was created.		 * 		 * @param analysis the Analysis		 */		public void setAnalysis(@Nullable Analysis analysis) {			this.analysisSetExplicitly = true;			this.analysis = analysis;		}		/**		 * Record that an AnalysisException occurred while attempting		 * to create the Analysis.		 * 		 * @param analysisException the AnalysisException		 */		public void setAnalysisException(AnalysisException analysisException) {			this.analysisException = analysisException;		}		/**		 * Record that a CFGBuilderException occurred while attempting		 * to create the Analysis.		 * 		 * @param cfgBuilderException the CFGBuilderException		 */		public void setCFGBuilderException(CFGBuilderException cfgBuilderException) {			this.cfgBuilderException = cfgBuilderException;		}		/**		 * Record that a DataflowAnalysisException occurred while attempting		 * to create the Analysis.		 *  		 * @param dataflowException the DataflowAnalysisException		 */		public void setDataflowAnalysisException(DataflowAnalysisException dataflowException) {			this.dataflowAnalysisException = dataflowException;		}	}	/**	 * Abstract factory class for creating analysis objects.	 * Handles caching of analysis results for a method.	 */	private abstract class AnalysisFactory <Analysis> {		private String analysisName;		private HashMap<Method, AnalysisResult<Analysis>> map =			new HashMap<Method, ClassContext.AnalysisResult<Analysis>>();		/**		 * Constructor.		 * 		 * @param analysisName name of the analysis factory: for diagnostics/debugging		 */		public AnalysisFactory(String analysisName) {			this.analysisName = analysisName;			analysisFactoryList.add(this);		}		/**		 * Get the Analysis for given method.		 * If Analysis has already been performed, the cached result is		 * returned.		 * 		 * @param method the method to analyze		 * @return the Analysis object representing the result of analyzing the method		 * @throws CFGBuilderException       if the CFG can't be constructed for the method		 * @throws DataflowAnalysisException if dataflow analysis fails on the method		 */		@CheckForNull public Analysis getAnalysis(Method method) throws CFGBuilderException, DataflowAnalysisException {			AnalysisResult<Analysis> result = map.get(method);			if (result == null) {				if (TIME_ANALYSES) {					++depth;					indent();					System.out.println("CC: Starting " + analysisName + " for " +							SignatureConverter.convertMethodSignature(jclass, method) + ":");				}				long begin = System.currentTimeMillis();				// Create a new AnalysisResult				result = new AnalysisResult<Analysis>();				// Attempt to create the Analysis and store it in the AnalysisResult.				// If an exception occurs, record it in the AnalysisResult.				Analysis analysis;				try {					analysis = analyze(method);					result.setAnalysis(analysis);				} catch (CFGBuilderException e) {					result.setCFGBuilderException(e);				} catch (DataflowAnalysisException e) {					result.setDataflowAnalysisException(e);				} catch (AnalysisException e) {					result.setAnalysisException(e);				}				if (TIME_ANALYSES) {					long end = System.currentTimeMillis();					indent();					System.out.println("CC: finished " + analysisName + " in " + (end - begin) + " millis");					--depth;				}				// Cache the outcome of this analysis attempt.				map.put(method, result);			}			return result.getAnalysis();		}		@CheckForNull protected abstract Analysis analyze(Method method)				throws CFGBuilderException, DataflowAnalysisException;		/**		 * @return true if this analysis factory is a dataflow analysis,		 *          false if not		 */		public abstract boolean isDataflow();		/**		 * Purge result for given method.		 * 		 * @param method the method whose analysis result should purged 		 */		public void purge(Method method) {			map.remove(method);		}	}	private abstract class NoExceptionAnalysisFactory <Analysis> extends AnalysisFactory<Analysis> {		public NoExceptionAnalysisFactory(String analysisName) {			super(analysisName);		}		@Override		public Analysis getAnalysis(Method method) {			try {				return super.getAnalysis(method);			} catch (DataflowAnalysisException e) {				throw new IllegalStateException("Should not happen");			} catch (CFGBuilderException e) {				throw new IllegalStateException("Should not happen");			}		}		/* (non-Javadoc)		 * @see edu.umd.cs.findbugs.ba.ClassContext.AnalysisFactory#isDataflow()		 */		@Override		public boolean isDataflow() {			return false;		}	}	private abstract class NoDataflowAnalysisFactory <Analysis> extends AnalysisFactory<Analysis> {		public NoDataflowAnalysisFactory(String analysisName) {			super(analysisName);		}		@Override		public Analysis getAnalysis(Method method) throws CFGBuilderException {			try {				return super.getAnalysis(method);			} catch (DataflowAnalysisException e) {				throw new IllegalStateException("Should not happen");			}		}		/* (non-Javadoc)		 * @see edu.umd.cs.findbugs.ba.ClassContext.AnalysisFactory#isDataflow()		 */		@Override		public boolean isDataflow() {			return false;		}	}	private final Set<String> busyCFGSet = new HashSet<String>();	private class CFGFactory extends AnalysisFactory<CFG> {		public CFGFactory() {			super("CFG construction");		}		@Override		public CFG getAnalysis(Method method) throws CFGBuilderException {			try {				return super.getAnalysis(method);			} catch (DataflowAnalysisException e) {				throw new IllegalStateException("Should not happen");			}		}		public CFG getRawCFG(Method method) throws CFGBuilderException {			return getAnalysis(method);		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -