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

📄 findrefcomparison.java

📁 一个查找java程序里bug的程序的源代码,该程序本身也是java写的,对提高java编程水平很有用
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * FindBugs - Find bugs in Java programs * Copyright (C) 2003,2004 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.detect;import java.util.*;import edu.umd.cs.findbugs.BugInstance;import edu.umd.cs.findbugs.BugReporter;import edu.umd.cs.findbugs.Detector;import edu.umd.cs.findbugs.ba.*;import org.apache.bcel.Constants;import org.apache.bcel.classfile.Field;import org.apache.bcel.classfile.JavaClass;import org.apache.bcel.classfile.Method;import org.apache.bcel.generic.*;public class FindRefComparison implements Detector, ExtendedTypes {	private static final boolean DEBUG = Boolean.getBoolean("frc.debug");	private static final boolean REPORT_ALL_REF_COMPARISONS = Boolean.getBoolean("findbugs.refcomp.reportAll");	/**	 * Classes that are suspicious if compared by reference.	 */	private static final HashSet<String> suspiciousSet = new HashSet<String>();	static {		suspiciousSet.add("java.lang.Boolean");		suspiciousSet.add("java.lang.Byte");		suspiciousSet.add("java.lang.Character");		suspiciousSet.add("java.lang.Double");		suspiciousSet.add("java.lang.Float");		suspiciousSet.add("java.lang.Integer");		suspiciousSet.add("java.lang.Long");		suspiciousSet.add("java.lang.Short");	}	/**	 * Set of opcodes that invoke instance methods on an object.	 */	private static final BitSet invokeInstanceSet = new BitSet();	static {		invokeInstanceSet.set(Constants.INVOKEVIRTUAL);		invokeInstanceSet.set(Constants.INVOKEINTERFACE);		invokeInstanceSet.set(Constants.INVOKESPECIAL);	}	/**	 * Set of bytecodes using for prescreening.	 */	private static final BitSet prescreenSet = new BitSet();	static {		prescreenSet.or(invokeInstanceSet);		prescreenSet.set(Constants.IF_ACMPEQ);		prescreenSet.set(Constants.IF_ACMPNE);	}	/* ----------------------------------------------------------------------	 * Helper classes	 * ---------------------------------------------------------------------- */	private static final byte T_DYNAMIC_STRING = T_AVAIL_TYPE + 0;	private static final byte T_STATIC_STRING = T_AVAIL_TYPE + 1;	private static final String STRING_SIGNATURE = "Ljava/lang/String;";	/**	 * Type representing a dynamically created String.	 * This sort of String should never be compared using reference	 * equality.	 */	private static class DynamicStringType extends ObjectType {		public DynamicStringType() {			super("java.lang.String");		}		public byte getType() {			return T_DYNAMIC_STRING;		}		public int hashCode() {			return System.identityHashCode(this);		}		public boolean equals(Object o) {			return o == this;		}		public String toString() {			return "<dynamic string>";		}	}	private static final Type dynamicStringTypeInstance = new DynamicStringType();	/**	 * Type representing a static String.	 * E.g., interned strings and constant strings.	 * It is generally OK to compare this sort of String	 * using reference equality.	 */	private static class StaticStringType extends ObjectType {		public StaticStringType() {			super("java.lang.String");		}		public byte getType() {			return T_STATIC_STRING;		}		public int hashCode() {			return System.identityHashCode(this);		}		public boolean equals(Object o) {			return o == this;		}		public String toString() {			return "<static string>";		}	}	private static final Type staticStringTypeInstance = new StaticStringType();	private static class RefComparisonTypeFrameModelingVisitor extends TypeFrameModelingVisitor {		private RepositoryLookupFailureCallback lookupFailureCallback;		public RefComparisonTypeFrameModelingVisitor(ConstantPoolGen cpg, RepositoryLookupFailureCallback lookupFailureCallback) {			super(cpg);			this.lookupFailureCallback = lookupFailureCallback;		}		// Override handlers for bytecodes that may return String objects		// known to be dynamic or static.		public void visitINVOKESTATIC(INVOKESTATIC obj) {			consumeStack(obj);			if (returnsString(obj)) {				String className = obj.getClassName(getCPG());				if (className.equals("java.lang.String")) {					pushValue(dynamicStringTypeInstance);				} else {					pushReturnType(obj);				}			} else {				pushReturnType(obj);			}		}		public void visitINVOKESPECIAL(INVOKESPECIAL obj) {			handleInstanceMethod(obj);		}		public void visitINVOKEINTERFACE(INVOKEINTERFACE obj) {			handleInstanceMethod(obj);		}		public void visitINVOKEVIRTUAL(INVOKEVIRTUAL obj) {			handleInstanceMethod(obj);		}		private boolean returnsString(InvokeInstruction inv) {			String methodSig = inv.getSignature(getCPG());			return methodSig.endsWith(")Ljava/lang/String;");		}		private void handleInstanceMethod(InvokeInstruction obj) {			consumeStack(obj);			if (returnsString(obj)) {				String className = obj.getClassName(getCPG());				String methodName = obj.getName(getCPG());				// System.out.println(className + "." + methodName);				if (methodName.equals("intern") && className.equals("java.lang.String")) {					sawStringIntern = true;					pushValue(staticStringTypeInstance);				} else if (methodName.equals("toString")				        || className.equals("java.lang.String")) {					pushValue(dynamicStringTypeInstance);					// System.out.println("  dynamic");				} else					pushReturnType(obj);			} else				pushReturnType(obj);		}		public void visitLDC(LDC obj) {			Type type = obj.getType(getCPG());			pushValue(isString(type) ? staticStringTypeInstance : type);		}		public void visitLDC2_W(LDC2_W obj) {			Type type = obj.getType(getCPG());			pushValue(isString(type) ? staticStringTypeInstance : type);		}		private boolean isString(Type type) {			return type.getSignature().equals(STRING_SIGNATURE);		}		public void visitGETSTATIC(GETSTATIC obj) {			handleLoad(obj);		}		public void visitGETFIELD(GETFIELD obj) {			handleLoad(obj);		}		private void handleLoad(FieldInstruction obj) {			consumeStack(obj);			Type type = obj.getType(getCPG());			if (type.getSignature().equals(STRING_SIGNATURE)) {				try {					String className = obj.getClassName(getCPG());					String fieldName = obj.getName(getCPG());					Field field = Hierarchy.findField(className, fieldName);					if (field != null) {						// If the field is final, we'll assume that the String value						// is static.						if (field.isFinal())							pushValue(staticStringTypeInstance);						else							pushValue(type);						return;					}				} catch (ClassNotFoundException ex) {					lookupFailureCallback.reportMissingClass(ex);				}			}			pushValue(type);		}	}	/**	 * Type merger to use the extended String types.	 */	private static class RefComparisonTypeMerger extends StandardTypeMerger {		public RefComparisonTypeMerger(RepositoryLookupFailureCallback lookupFailureCallback,		                               ExceptionSetFactory exceptionSetFactory) {			super(lookupFailureCallback, exceptionSetFactory);		}		protected boolean isReferenceType(byte type) {			return super.isReferenceType(type) || type == T_STATIC_STRING || type == T_DYNAMIC_STRING;		}		protected Type mergeReferenceTypes(ReferenceType aRef, ReferenceType bRef) throws DataflowAnalysisException {			byte aType = aRef.getType();			byte bType = bRef.getType();			if (isExtendedStringType(aType) || isExtendedStringType(bType)) {				// If both types are the same extended String type,				// then the same type is returned.  Otherwise, extended				// types are downgraded to plain java.lang.String,				// and a standard merge is applied.				if (aType == bType)					return aRef;				if (isExtendedStringType(aType))					aRef = Type.STRING;				if (isExtendedStringType(bType))					bRef = Type.STRING;			}			return super.mergeReferenceTypes(aRef, bRef);		}		private boolean isExtendedStringType(byte type) {			return type == T_DYNAMIC_STRING || type == T_STATIC_STRING;		}	}	/* ----------------------------------------------------------------------	 * Fields	 * ---------------------------------------------------------------------- */	private BugReporter bugReporter;	//private AnalysisContext analysisContext;	private BugInstance stringComparison;	private BugInstance refComparison;	/* ----------------------------------------------------------------------	 * Implementation	 * ---------------------------------------------------------------------- */	public FindRefComparison(BugReporter bugReporter) {		this.bugReporter = bugReporter;	}	public void setAnalysisContext(AnalysisContext analysisContext) {		//this.analysisContext = analysisContext;	}	// XXX BAD EVIL NOT THREAD SAFE YUCK FIXME

⌨️ 快捷键说明

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