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

📄 sourcelineannotation.java

📁 A static analysis tool to find bugs in Java programs
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
	 * source line number for a visited instruction.	 *	 * @param classContext the ClassContext	 * @param methodGen the MethodGen object representing the method	 * @param handle    the InstructionHandle containing the visited instruction	 * @return the SourceLineAnnotation, or null if we do not have line number information	 *         for the instruction	 */	public static SourceLineAnnotation fromVisitedInstruction(ClassContext classContext, MethodGen methodGen, String sourceFile, @NonNull InstructionHandle handle) {		LineNumberTable table = methodGen.getLineNumberTable(methodGen.getConstantPool());		String className = methodGen.getClassName();		int bytecodeOffset = handle.getPosition();		if (table == null)			return createUnknown(className, sourceFile, bytecodeOffset, bytecodeOffset);		int lineNumber = table.getSourceLine(handle.getPosition());		return new SourceLineAnnotation(				className, sourceFile, lineNumber, lineNumber, bytecodeOffset, bytecodeOffset)				.addInstructionContext(classContext, classContext.getMethod(methodGen));	}	/**	 * Factory method for creating a source line annotation describing	 * the source line numbers for a range of instruction in a method.	 *	 * @param classContext theClassContext	 * @param methodGen the method	 * @param start     the start instruction	 * @param end       the end instruction (inclusive)	 */	public static SourceLineAnnotation fromVisitedInstructionRange(			ClassContext classContext, MethodGen methodGen, String sourceFile, InstructionHandle start, InstructionHandle end) {		LineNumberTable lineNumberTable = methodGen.getLineNumberTable(methodGen.getConstantPool());		String className = methodGen.getClassName();		if (lineNumberTable == null)			return createUnknown(className, sourceFile, start.getPosition(), end.getPosition());		int startLine = lineNumberTable.getSourceLine(start.getPosition());		int endLine = lineNumberTable.getSourceLine(end.getPosition());		return new SourceLineAnnotation(				className, sourceFile, startLine, endLine, start.getPosition(), end.getPosition())				.addInstructionContext(classContext, classContext.getMethod(methodGen));	}	private static LineNumberTable getLineNumberTable(PreorderVisitor visitor) {		Code code = visitor.getMethod().getCode();		if (code == null)			return null;		return code.getLineNumberTable();	}	private static final int NUM_CONTEXT_OPCODES = 5;	/**	 * Fill in context information about surrounding opcodes.	 * 	 * @param classContext the ClassContext	 * @param method       the method	 */	private SourceLineAnnotation addInstructionContext(ClassContext classContext, Method method) {		// For now, do nothing.		return this;	}	/**	 * Get the class name.	 */	public String getClassName() {		return className;	}	/**	 * Get the source file name.	 */	public String getSourceFile() {		return sourceFile;	}	/**	 * Is the source file known?	 */	public boolean isSourceFileKnown() {		return !sourceFile.equals(UNKNOWN_SOURCE_FILE);	}	/**	 * Set the source file name.	 *	 * @param sourceFile the source file name	 */	public void setSourceFile(String sourceFile) {		this.sourceFile = sourceFile;	}	/**	 * Get the simple class name (the part of the name after the dot)	 */	public String getSimpleClassName() {		int lastDot = className.lastIndexOf('.');		return className.substring(lastDot+1);	}	/**	 * Get the package name.	 */	public String getPackageName() {		int lastDot = className.lastIndexOf('.');		if (lastDot < 0)			return "";		else			return className.substring(0, lastDot);	}	/**	 * Get the start line (inclusive).	 */	public int getStartLine() {		return startLine;	}	/**	 * Get the ending line (inclusive).	 */	public int getEndLine() {		return endLine;	}	/**	 * Get start bytecode (inclusive).	 */	public int getStartBytecode() {		return startBytecode;	}	/**	 * Get end bytecode (inclusive).	 */	public int getEndBytecode() {		return endBytecode;	}	/**	 * Is this an unknown source line annotation?	 */	public boolean isUnknown() {		return startLine < 0 || endLine < 0;	}	public void accept(BugAnnotationVisitor visitor) {		visitor.visitSourceLineAnnotation(this);	}	public String format(String key, ClassAnnotation primaryClass) {		if (key.equals("hash")) return "";		if (key.equals("")) {			StringBuffer buf = new StringBuffer();			buf.append(sourceFile);			appendLines(buf);			return buf.toString();		} else if (key.equals("lineNumber")) {			StringBuffer buf = new StringBuffer();			appendLinesRaw(buf);			return buf.toString();		} else if (key.equals("full")) {			StringBuffer buf = new StringBuffer();			String pkgName = getPackageName();			if (!pkgName.equals("")) {				buf.append(pkgName.replace('.', '/'));				buf.append('/');			}			buf.append(sourceFile);			appendLines(buf);			return buf.toString();		} else			throw new IllegalArgumentException("Unknown format key " + key);	}	private void appendLines(StringBuffer buf) {		if (isUnknown()) return;		buf.append(":[");		appendLinesRaw(buf);		buf.append(']');	}	private void appendLinesRaw(StringBuffer buf) {		if (isUnknown()) return;		if (startLine == endLine) {			buf.append("line ");			buf.append(startLine);		} else {			buf.append("lines ");			buf.append(startLine);			buf.append('-');			buf.append(endLine);		}	}	public String getDescription() {		return description;	}	public void setDescription(String description) {		this.description = description;	}	@Override	public String toString() {		String desc = description;		if (desc.equals(DEFAULT_ROLE) && isUnknown())			desc = DEFAULT_ROLE_UNKNOWN_LINE;		String pattern = I18N.instance().getAnnotationDescription(desc);		FindBugsMessageFormat format = new FindBugsMessageFormat(pattern);		return format.format(new BugAnnotation[]{this}, null);	}	public int compareTo(BugAnnotation o) {		if (!(o instanceof SourceLineAnnotation)) // All BugAnnotations must be comparable			return this.getClass().getName().compareTo(o.getClass().getName());		SourceLineAnnotation other = (SourceLineAnnotation) o;		int cmp = className.compareTo(other.className);		if (cmp != 0)			return cmp;		cmp = startLine - other.startLine;		if (cmp != 0)			return cmp;		return endLine - other.endLine;	}	@Override	public int hashCode() {		return className.hashCode() + startLine + 3 * endLine;	}	@Override	public boolean equals(Object o) {		if (!(o instanceof SourceLineAnnotation))			return false;		SourceLineAnnotation other = (SourceLineAnnotation) o;		return className.equals(other.className)				&& startLine == other.startLine				&& endLine == other.endLine;	}	/* ----------------------------------------------------------------------	 * XML Conversion support	 * ---------------------------------------------------------------------- */	private static final String ELEMENT_NAME = "SourceLine";	public void writeXML(XMLOutput xmlOutput) throws IOException {		writeXML(xmlOutput, false);	}	public void writeXML(XMLOutput xmlOutput, boolean addMessages) throws IOException {		String classname = getClassName();		String packageName = "";		if (classname.indexOf('.') > 0) 			packageName = classname.substring(0,1+classname.lastIndexOf('.'));		XMLAttributeList attributeList = new XMLAttributeList()			.addAttribute("classname", classname);		int n = getStartLine(); // start/end are now optional (were too many "-1"s in the xml)		if (n >= 0) attributeList.addAttribute("start", String.valueOf(n));		n = getEndLine();		if (n >= 0) attributeList.addAttribute("end", String.valueOf(n));		n = getStartBytecode(); // startBytecode/endBytecode haven't been set for a while now		if (n >= 0) attributeList.addAttribute("startBytecode", String.valueOf(n));		n = getEndBytecode();		if (n >= 0) attributeList.addAttribute("endBytecode", String.valueOf(n));		if (isSourceFileKnown()) {			attributeList.addAttribute("sourcefile", sourceFile);			attributeList.addAttribute("sourcepath", packageName.replace('.', '/')+sourceFile);		}		String role = getDescription();		if (!role.equals(DEFAULT_ROLE))			attributeList.addAttribute("role", getDescription());		if (synthetic) 			attributeList.addAttribute("synthetic", "true");		if (addMessages) {			xmlOutput.openTag(ELEMENT_NAME, attributeList);			xmlOutput.openTag("Message");			xmlOutput.writeText(this.toString());			xmlOutput.closeTag("Message");			xmlOutput.closeTag(ELEMENT_NAME);		} else {			xmlOutput.openCloseTag(ELEMENT_NAME, attributeList);		}	}	/**	 * @param synthetic The synthetic to set.	 */	public void setSynthetic(boolean synthetic) {		this.synthetic = synthetic;	}	/**	 * @return Returns the synthetic.	 */	public boolean isSynthetic() {		return synthetic;	}	public boolean isSignificant() {		return false;	}	/**	 * @param className	 * @param methodName	 * @param methodSig	 * @return	 */	static SourceLineAnnotation getSourceAnnotationForMethod(			String className, String methodName, String methodSig) {		JavaClassAndMethod targetMethod = null;		Code code = null;		try {			JavaClass targetClass = AnalysisContext.currentAnalysisContext().lookupClass(className);			targetMethod = Hierarchy.findMethod(targetClass, methodName, methodSig);			if (targetMethod != null) {				Method method = targetMethod.getMethod();				if (method != null) code = method.getCode();			}		} catch (ClassNotFoundException e) {			AnalysisContext.reportMissingClass(e);		}		SourceInfoMap sourceInfoMap = AnalysisContext.currentAnalysisContext().getSourceInfoMap();		SourceInfoMap.SourceLineRange range = sourceInfoMap.getMethodLine(className, methodName, methodSig);		if (range != null) 			return new SourceLineAnnotation(					className,					AnalysisContext.currentAnalysisContext().lookupSourceFile(className),					range.getStart(),					range.getEnd(),					0,					code == null ? -1 : code.getLength());		if (sourceInfoMap.fallBackToClassfile() && targetMethod != null) 			return  forEntireMethod(					targetMethod.getJavaClass(), targetMethod.getMethod());		// If we couldn't find the source lines,		// create an unknown source line annotation referencing		// the class and source file.		return createUnknown(className);	}/** * @param className * @return */	static SourceLineAnnotation getSourceAnnotationForClass(String className, String sourceFileName) {		int lastLine = -1;		int firstLine = Integer.MAX_VALUE;		try {			JavaClass targetClass = AnalysisContext.currentAnalysisContext().lookupClass(className);			for (Method m : targetClass.getMethods()) {				Code c = m.getCode();				if (c != null) {					LineNumberTable table = c.getLineNumberTable();					if (table != null)						for (LineNumber line : table.getLineNumberTable()) {							lastLine = Math.max(lastLine, line.getLineNumber());							firstLine = Math.min(firstLine, line.getLineNumber());						}				}			}		} catch (ClassNotFoundException e) {			AnalysisContext.reportMissingClass(e);		}		if (firstLine < Integer.MAX_VALUE)			return new SourceLineAnnotation(className, sourceFileName,					firstLine, lastLine, -1, -1);		return   SourceLineAnnotation.createUnknown(className, sourceFileName);	}}// vim:ts=4

⌨️ 快捷键说明

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