📄 buginstance.java
字号:
return this; } /** * Add a field annotation for the field which is being visited by * given visitor. * * @param visitor the visitor * @return this object */ public BugInstance addVisitedField(PreorderVisitor visitor) { FieldAnnotation f = FieldAnnotation.fromVisitedField(visitor); addField(f); return this; } /* ---------------------------------------------------------------------- * Method annotation adders * ---------------------------------------------------------------------- */ /** * Add a method annotation. If this is the first method annotation added, * it becomes the primary method annotation. * * @param className name of the class containing the method * @param methodName name of the method * @param methodSig type signature of the method * @return this object */ public BugInstance addMethod(String className, String methodName, String methodSig) { addMethod(new MethodAnnotation(className, methodName, methodSig)); return this; } /** * Add a method annotation. If this is the first method annotation added, * it becomes the primary method annotation. * If the method has source line information, then a SourceLineAnnotation * is added to the method. * * @param methodGen the MethodGen object for the method * @param sourceFile source file method is defined in * @return this object */ public BugInstance addMethod(MethodGen methodGen, String sourceFile) { MethodAnnotation methodAnnotation = new MethodAnnotation(methodGen.getClassName(), methodGen.getName(), methodGen.getSignature()); addMethod(methodAnnotation); addSourceLinesForMethod(methodAnnotation, SourceLineAnnotation.fromVisitedMethod(methodGen, sourceFile)); return this; } /** * Add a method annotation for the method which the given visitor is currently visiting. * If the method has source line information, then a SourceLineAnnotation * is added to the method. * * @param visitor the BetterVisitor * @return this object */ public BugInstance addMethod(PreorderVisitor visitor) { MethodAnnotation methodAnnotation = MethodAnnotation.fromVisitedMethod(visitor); addMethod(methodAnnotation); addSourceLinesForMethod(methodAnnotation, SourceLineAnnotation.fromVisitedMethod(visitor)); return this; } /** * Add a method annotation for the method which has been called * by the method currently being visited by given visitor. * Assumes that the visitor has just looked at an invoke instruction * of some kind. * * @param visitor the DismantleBytecode object * @return this object */ public BugInstance addCalledMethod(DismantleBytecode visitor) { String className = visitor.getDottedClassConstantOperand(); String methodName = visitor.getNameConstantOperand(); String methodSig = visitor.getDottedSigConstantOperand(); addMethod(className, methodName, methodSig); describe("METHOD_CALLED"); return this; } /** * Add a method annotation. * * @return this object */ public BugInstance addCalledMethod(String className, String methodName, String methodSig) { addMethod(className, methodName, methodSig); describe("METHOD_CALLED"); return this; } /** * Add a method annotation for the method which is called by given * instruction. * * @param methodGen the method containing the call * @param inv the InvokeInstruction * @return this object */ public BugInstance addCalledMethod(MethodGen methodGen, InvokeInstruction inv) { ConstantPoolGen cpg = methodGen.getConstantPool(); String className = inv.getClassName(cpg); String methodName = inv.getMethodName(cpg); String methodSig = inv.getSignature(cpg); addMethod(className, methodName, methodSig); describe("METHOD_CALLED"); return this; } /** * Add a method annotation. If this is the first method annotation added, * it becomes the primary method annotation. * * @param methodAnnotation the method annotation * @return this object */ public BugInstance addMethod(MethodAnnotation methodAnnotation) { add(methodAnnotation); return this; } /* ---------------------------------------------------------------------- * Integer annotation adders * ---------------------------------------------------------------------- */ /** * Add an integer annotation. * * @param value the integer value * @return this object */ public BugInstance addInt(int value) { add(new IntAnnotation(value)); return this; } /* ---------------------------------------------------------------------- * Source line annotation adders * ---------------------------------------------------------------------- */ /** * Add a source line annotation. * * @param sourceLine the source line annotation * @return this object */ public BugInstance addSourceLine(SourceLineAnnotation sourceLine) { add(sourceLine); return this; } /** * Add a source line annotation for instruction whose PC is given * in the method that the given visitor is currently visiting. * Note that if the method does not have line number information, then * no source line annotation will be added. * * @param visitor a BetterVisitor that is currently visiting the method * @param pc bytecode offset of the instruction * @return this object */ public BugInstance addSourceLine(PreorderVisitor visitor, int pc) { SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation.fromVisitedInstruction(visitor, pc); if (sourceLineAnnotation != null) add(sourceLineAnnotation); return this; } /** * Add a source line annotation for the given instruction in the given method. * Note that if the method does not have line number information, then * no source line annotation will be added. * * @param methodGen the method being visited * @param sourceFile source file the method is defined in * @param handle the InstructionHandle containing the visited instruction * @return this object */ public BugInstance addSourceLine(MethodGen methodGen, String sourceFile, InstructionHandle handle) { SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation.fromVisitedInstruction(methodGen, sourceFile, handle); if (sourceLineAnnotation != null) add(sourceLineAnnotation); return this; } /** * Add a source line annotation describing a range of instructions. * * @param methodGen the method * @param sourceFile source file the method is defined in * @param start the start instruction in the range * @param end the end instruction in the range (inclusive) * @return this object */ public BugInstance addSourceLine(MethodGen methodGen, String sourceFile, InstructionHandle start, InstructionHandle end) { // Make sure start and end are really in the right order. if (start.getPosition() > end.getPosition()) { InstructionHandle tmp = start; start = end; end = tmp; } SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation.fromVisitedInstructionRange(methodGen, sourceFile, start, end); if (sourceLineAnnotation != null) add(sourceLineAnnotation); return this; } /** * Add a source line annotation describing the * source line numbers for a range of instructions in the method being * visited by the given visitor. * Note that if the method does not have line number information, then * no source line annotation will be added. * * @param visitor a BetterVisitor which is visiting the method * @param startPC the bytecode offset of the start instruction in the range * @param endPC the bytecode offset of the end instruction in the range * @return this object */ public BugInstance addSourceLineRange(PreorderVisitor visitor, int startPC, int endPC) { SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation.fromVisitedInstructionRange(visitor, startPC, endPC); if (sourceLineAnnotation != null) add(sourceLineAnnotation); return this; } /** * Add a source line annotation for instruction currently being visited * by given visitor. * Note that if the method does not have line number information, then * no source line annotation will be added. * * @param visitor a DismantleBytecode visitor that is currently visiting the instruction * @return this object */ public BugInstance addSourceLine(DismantleBytecode visitor) { SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation.fromVisitedInstruction(visitor); if (sourceLineAnnotation != null) add(sourceLineAnnotation); return this; } /** * Add a non-specific source line annotation. * This will result in the entire source file being displayed. * * @param className the class name * @param sourceFile the source file name * @return this object */ public BugInstance addUnknownSourceLine(String className, String sourceFile) { SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation.createUnknown(className, sourceFile); if (sourceLineAnnotation != null) add(sourceLineAnnotation); return this; } /* ---------------------------------------------------------------------- * Formatting support * ---------------------------------------------------------------------- */ /** * Format a string describing this bug instance. * * @return the description */ public String getMessage() { String pattern = I18N.instance().getMessage(type); FindBugsMessageFormat format = new FindBugsMessageFormat(pattern); return format.format((BugAnnotation[]) annotationList.toArray(new BugAnnotation[annotationList.size()])); } /** * Add a description to the most recently added bug annotation. * * @param description the description to add * @return this object */ public BugInstance describe(String description) { annotationList.get(annotationList.size() - 1).setDescription(description); return this; } /** * Convert to String. * This method returns the "short" message describing the bug, * as opposed to the longer format returned by getMessage(). * The short format is appropriate for the tree view in a GUI, * where the annotations are listed separately as part of the overall * bug instance. */ public String toString() { return I18N.instance().getShortMessage(type); } /* ---------------------------------------------------------------------- * XML Conversion support * ---------------------------------------------------------------------- */ public void writeXML(XMLOutput xmlOutput) throws IOException { XMLAttributeList attributeList = new XMLAttributeList() .addAttribute("type", type) .addAttribute("priority", String.valueOf(priority)); BugPattern pattern = getBugPattern(); if (pattern != null) { // The bug abbreviation and pattern category are // emitted into the XML for informational purposes only. // (The information is redundant, but might be useful // for processing tools that want to make sense of // bug instances without looking at the plugin descriptor.) attributeList.addAttribute("abbrev", pattern.getAbbrev()); attributeList.addAttribute("category", pattern.getCategory()); } xmlOutput.openTag(ELEMENT_NAME, attributeList); if (!annotationText.equals("")) { xmlOutput.openTag("UserAnnotation"); xmlOutput.writeCDATA(annotationText); xmlOutput.closeTag("UserAnnotation"); } XMLOutputUtil.writeCollection(xmlOutput, annotationList); xmlOutput.closeTag(ELEMENT_NAME); } private static final String ELEMENT_NAME = "BugInstance"; private static final String USER_ANNOTATION_ELEMENT_NAME = "UserAnnotation"; /* ---------------------------------------------------------------------- * Implementation * ---------------------------------------------------------------------- */ void add(BugAnnotation annotation) { if (annotation == null) throw new IllegalStateException("Missing BugAnnotation!"); // Add to list annotationList.add(annotation); // This object is being modified, so the cached hashcode // must be invalidated cachedHashCode = INVALID_HASH_CODE; if ((annotation instanceof ClassAnnotation) && primaryClassAnnotation == null) primaryClassAnnotation = (ClassAnnotation) annotation; if ((annotation instanceof MethodAnnotation) && primaryMethodAnnotation == null) primaryMethodAnnotation = (MethodAnnotation) annotation; if ((annotation instanceof FieldAnnotation) && primaryFieldAnnotation == null) primaryFieldAnnotation = (FieldAnnotation) annotation; } private void addSourceLinesForMethod(MethodAnnotation methodAnnotation, SourceLineAnnotation sourceLineAnnotation) { if (sourceLineAnnotation != null) { // Note: we don't add the source line annotation directly to // the bug instance. Instead, we stash it in the MethodAnnotation. // It is much more useful there, and it would just be distracting // if it were displayed in the UI, since it would compete for attention // with the actual bug location source line annotation (which is much // more important and interesting). methodAnnotation.setSourceLines(sourceLineAnnotation); } } public int hashCode() { if (cachedHashCode == INVALID_HASH_CODE) { int hashcode = type.hashCode() + priority; Iterator<BugAnnotation> i = annotationIterator(); while (i.hasNext()) hashcode += i.next().hashCode(); if (hashcode == INVALID_HASH_CODE) hashcode = INVALID_HASH_CODE+1; cachedHashCode = hashcode; } return cachedHashCode; } public boolean equals(Object o) { if (!(o instanceof BugInstance)) return false; BugInstance other = (BugInstance) o; if (!type.equals(other.type) || priority != other.priority) return false; if (annotationList.size() != other.annotationList.size()) return false; int numAnnotations = annotationList.size(); for (int i = 0; i < numAnnotations; ++i) { BugAnnotation lhs = annotationList.get(i); BugAnnotation rhs = other.annotationList.get(i); if (!lhs.equals(rhs)) return false; } return true; } public int compareTo(Object o) { BugInstance other = (BugInstance) o; int cmp; cmp = type.compareTo(other.type); if (cmp != 0) return cmp; cmp = priority - other.priority; if (cmp != 0) return cmp; // Compare BugAnnotations lexicographically int pfxLen = Math.min(annotationList.size(), other.annotationList.size()); for (int i = 0; i < pfxLen; ++i) { BugAnnotation lhs = annotationList.get(i); BugAnnotation rhs = other.annotationList.get(i); cmp = lhs.compareTo(rhs); if (cmp != 0) return cmp; } // All elements in prefix were the same, // so use number of elements to decide return annotationList.size() - other.annotationList.size(); }}// vim:ts=4
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -