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

📄 classcontext.java

📁 A static analysis tool to find bugs in Java programs
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
		@Override		protected CompactLocationNumbering analyze(Method method) throws CFGBuilderException, DataflowAnalysisException {			if (method.getCode() == null) {				return null;			}			CFG cfg = getCFG(method);			return new CompactLocationNumbering(cfg);		}	};	private DataflowAnalysisFactory<DefinitelyNullSetDataflow> definitelyNullSetDataflowFactory =		new DataflowAnalysisFactory<DefinitelyNullSetDataflow>("definitely null set dataflow") {		/* (non-Javadoc)		 * @see edu.umd.cs.findbugs.ba.ClassContext.AnalysisFactory#analyze(org.apache.bcel.classfile.Method)		 */		@Override		protected DefinitelyNullSetDataflow analyze(Method method) throws CFGBuilderException, DataflowAnalysisException {			CFG cfg = getCFG(method);			DepthFirstSearch  dfs = getDepthFirstSearch(method);			ValueNumberDataflow vnaDataflow = getValueNumberDataflow(method);			CompactLocationNumbering compactLocationNumbering = getCompactLocationNumbering(method);			DefinitelyNullSetAnalysis analysis = new DefinitelyNullSetAnalysis(dfs, vnaDataflow, compactLocationNumbering);			DefinitelyNullSetDataflow dataflow = new DefinitelyNullSetDataflow(cfg, analysis);			dataflow.execute();			return dataflow;		}	};	private DataflowAnalysisFactory<ReturnPathTypeDataflow> returnPathTypeDataflowFactory =		new DataflowAnalysisFactory<ReturnPathTypeDataflow>("return path type dataflow") {		/* (non-Javadoc)		 * @see edu.umd.cs.findbugs.ba.ClassContext.AnalysisFactory#analyze(org.apache.bcel.classfile.Method)		 */		@Override		protected ReturnPathTypeDataflow analyze(Method method) throws CFGBuilderException, DataflowAnalysisException {			CFG cfg = getCFG(method);			DepthFirstSearch dfs = getDepthFirstSearch(method);			ReverseDepthFirstSearch rdfs = getReverseDepthFirstSearch(method);			ReturnPathTypeAnalysis analysis = new ReturnPathTypeAnalysis(cfg, rdfs, dfs);			ReturnPathTypeDataflow dataflow = new ReturnPathTypeDataflow(cfg, analysis);			dataflow.execute();			return dataflow;		}	};	private ClassGen classGen;	private AssignedFieldMap assignedFieldMap;	private AssertionMethods assertionMethods;	/* ----------------------------------------------------------------------	 * Public methods	 * ---------------------------------------------------------------------- */	/**	 * Constructor.	 *	 * @param jclass the JavaClass	 */	public ClassContext(JavaClass jclass, AnalysisContext analysisContext) {		this.jclass = jclass;		this.analysisContext = analysisContext;		this.classGen = null;		this.assignedFieldMap = null;		this.assertionMethods = null;	}	/**	 * Purge dataflow analysis results after CFG-pruning of given method.	 * 	 * @param method the method whose CFG has just been pruned	 */	void purgeAnalysisResultsAfterCFGPruning(Method method) {		for (AnalysisFactory<?> factory : analysisFactoryList) {			if (factory.isDataflow()) {				factory.purge(method);			}		}	}	/**	 * Get the JavaClass.	 */	public JavaClass getJavaClass() {		return jclass;	}	/**	 * Look up the Method represented by given MethodGen.	 * 	 * @param methodGen a MethodGen	 * @return the Method represented by the MethodGen	 */	public Method getMethod(MethodGen methodGen) {		Method[] methodList = jclass.getMethods();		for (Method method : methodList) {			if (method.getName().equals(methodGen.getName())					&& method.getSignature().equals(methodGen.getSignature())					&& method.getAccessFlags() == methodGen.getAccessFlags()) {				return method;			}		}		return null;	}	@CheckForNull List<Method> methodsInCallOrder = null;	public @NonNull List<Method> getMethodsInCallOrder() {		if (methodsInCallOrder != null) return methodsInCallOrder;		List<Method> methodList = Arrays.asList(getJavaClass().getMethods());		final Map<String, Method> map = new HashMap<String, Method>();		for (Method m : methodList) {			map.put(m.getName() + m.getSignature(), m);		}		final ConstantPoolGen cpg = getConstantPoolGen();		final String thisClassName = getJavaClass().getClassName();		methodsInCallOrder =  TopologicalSort.sortByCallGraph(methodList, new OutEdges<Method>() {			public Collection<Method> getOutEdges(Method method) {				HashSet<Method> result = new HashSet<Method>();				try {					CFG cfg = getCFG(method);					for (Iterator<Location> i = cfg.locationIterator(); i.hasNext();) {						Instruction ins = i.next().getHandle().getInstruction();						if (ins instanceof InvokeInstruction) {							InvokeInstruction inv = (InvokeInstruction) ins;							String className = inv.getClassName(cpg);							if (!thisClassName.equals(className)) continue;							String signature = inv.getSignature(cpg);							if (signature.indexOf('L') < 0 && signature.indexOf('[') < 0) continue;							String methodKey = inv.getMethodName(cpg) + signature;							Method method2 = map.get(methodKey);							if (method2 != null) result.add(method2);						}					}				} catch (CFGBuilderException e) {					AnalysisContext.logError("Error getting methods called by " + thisClassName + "." + method.getName() + ":"							+ method.getSignature(), e);				}				return result;			}		});		assert methodList.size() == methodsInCallOrder.size();		return methodsInCallOrder;	}	/**	 * Get the AnalysisContext.	 */	public AnalysisContext getAnalysisContext() {		return analysisContext;	}	/**	 * Get the RepositoryLookupFailureCallback.	 *	 * @return the RepositoryLookupFailureCallback	 */	public RepositoryLookupFailureCallback getLookupFailureCallback() {		return analysisContext.getLookupFailureCallback();	}	/**	 * Get a MethodGen object for given method.	 *	 * @param method the method	 * @return the MethodGen object for the method, or null	 *         if the method has no Code attribute (and thus cannot be analyzed)	 *         or if the method seems unprofitable to analyze	 */	@CheckForNull public MethodGen getMethodGen(Method method) {		return methodGenFactory.getAnalysis(method);	}	/**	 * Get a "raw" CFG for given method.	 * No pruning is done, although the CFG may already be pruned.	 *	 * @param method the method	 * @return the raw CFG	 */	public CFG getRawCFG(Method method) throws CFGBuilderException {		return cfgFactory.getRawCFG(method);	}	/**	 * Get a CFG for given method.	 * If pruning options are in effect, pruning will be done.	 * Because the CFG pruning can involve interprocedural analysis,	 * it is done on a best-effort basis, so the CFG returned might	 * not actually be pruned.	 *	 * @param method the method	 * @return the CFG	 * @throws CFGBuilderException if a CFG cannot be constructed for the method	 */	public CFG getCFG(Method method) throws CFGBuilderException {		if (method == cachedMethod) {			// System.out.println("hit on " + method.getName());			return cachedCFG;		}		if (false && cachedMethod != null) System.out.println(cachedMethod.getName() + " -> " + method.getName());		CFG cfg = cfgFactory.getRefinedCFG(method);		cachedMethod = method;		cachedCFG = cfg;		return cfg;	}	Method cachedMethod;	CFG cachedCFG = null;	/**	 * Get the ConstantPoolGen used to create the MethodGens	 * for this class.	 *	 * @return the ConstantPoolGen	 */	public @NonNull ConstantPoolGen getConstantPoolGen() {		if (classGen == null)			classGen = new ClassGen(jclass);		return classGen.getConstantPool();	}	/**	 * Get a UsagesRequiringNonNullValues for given method.	 *	 * @param method the method	 * @return the UsagesRequiringNonNullValues	 */	public UsagesRequiringNonNullValues getUsagesRequiringNonNullValues(Method method) throws DataflowAnalysisException, CFGBuilderException {		return derefFactory.getAnalysis(method);	}	/**	 * Get a ValueNumberDataflow for given method.	 *	 * @param method the method	 * @return the ValueNumberDataflow	 */	public ValueNumberDataflow getValueNumberDataflow(Method method) throws DataflowAnalysisException, CFGBuilderException {		return vnaDataflowFactory.getAnalysis(method);	}	/**	 * Get an IsNullValueDataflow for given method.	 *	 * @param method the method	 * @return the IsNullValueDataflow	 */	public IsNullValueDataflow getIsNullValueDataflow(Method method) throws DataflowAnalysisException, CFGBuilderException {		return invDataflowFactory.getAnalysis(method);	}	/**	 * Get a TypeDataflow for given method.	 *	 * @param method the method	 * @return the TypeDataflow	 */	public TypeDataflow getTypeDataflow(Method method) throws DataflowAnalysisException, CFGBuilderException {		return typeDataflowFactory.getAnalysis(method);	}	/**	 * Get a DepthFirstSearch for given method.	 *	 * @param method the method	 * @return the DepthFirstSearch	 */	public DepthFirstSearch getDepthFirstSearch(Method method) throws CFGBuilderException {		return dfsFactory.getAnalysis(method);	}	/**	 * Get a ReverseDepthFirstSearch for given method.	 *	 * @param method the method	 * @return the ReverseDepthFirstSearch	 */	public ReverseDepthFirstSearch getReverseDepthFirstSearch(Method method)			throws CFGBuilderException {		return rdfsFactory.getAnalysis(method);	}	static MapCache<XMethod,BitSet> cachedBitsets = new MapCache<XMethod, BitSet>(64);	static MapCache<XMethod,Set<Integer>> cachedLoopExits = new MapCache<XMethod, Set<Integer>>(13);	/**	 * Get a BitSet representing the bytecodes that are used in the given method.	 * This is useful for prescreening a method for the existence of particular instructions.	 * Because this step doesn't require building a MethodGen, it is very	 * fast and memory-efficient.  It may allow a Detector to avoid some	 * very expensive analysis, which is a Big Win for the user.	 *	 * @param method the method	 * @return the BitSet containing the opcodes which appear in the method,	 *          or null if the method has no code	 */	@CheckForNull   public BitSet getBytecodeSet(Method method) {		return getBytecodeSet(jclass, method);	}	/**	 * Get a BitSet representing the bytecodes that are used in the given method.	 * This is useful for prescreening a method for the existence of particular instructions.	 * Because this step doesn't require building a MethodGen, it is very	 * fast and memory-efficient.  It may allow a Detector to avoid some	 * very expensive analysis, which is a Big Win for the user.	 *	 * @param method the method	 * @return the BitSet containing the opcodes which appear in the method,	 *          or null if the method has no code	 */	@CheckForNull static public BitSet getBytecodeSet(JavaClass clazz, Method method) {				XMethod xmethod = XFactory.createXMethod(clazz, method);				if (cachedBitsets.containsKey(xmethod)) {					return cachedBitsets.get(xmethod);				}				Code code = method.getCode();				if (code == null)					return null;				byte[] instructionList = code.getCode();				// Create callback				UnpackedBytecodeCallback callback = new UnpackedBytecodeCallback(instructionList.length);				// Scan the method.				BytecodeScanner scanner = new BytecodeScanner();				scanner.scan(instructionList, callback);				UnpackedCode unpackedCode = callback.getUnpackedCode();				BitSet result =  null;				if (unpackedCode != null) result =  unpackedCode.getBytecodeSet();				cachedBitsets.put(xmethod, result);				return result;	}	@CheckForNull static public Set<Integer> getLoopExitBranches(Method method, MethodGen methodGen) {		XMethod xmethod = XFactory.createXMethod(methodGen);		if (cachedLoopExits.containsKey(xmethod)) {			return cachedLoopExits.get(xmethod);		}		Code code = method.getCode();		if (code == null)			return null;		byte[] instructionList = code.getCode();		Set<Integer> result = new HashSet<Integer>();		for(int i = 0; i < instructionList.length; i++)			if (checkForBranchExit(instructionList,i)) result.add(i);		if (result.size() == 0)			result = TigerSubstitutes.emptySet(); // alas, emptySet() is @since 1.5		cachedLoopExits.put(xmethod, result);		return result;}	static short getBranchOffset(byte [] codeBytes, int pos) {		int branchByte1 = 0xff & codeBytes[pos];		int branchByte2 = 0xff & codeBytes[pos+1];		int branchOffset = (short) (branchByte1 << 8 | branchByte2);		return (short) branchOffset;	}	static boolean checkForBranchExit(byte [] codeBytes, int pos) {		if (pos < 0 || pos+2 >= codeBytes.length) return false;

⌨️ 快捷键说明

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