Recently, I try deckard to find bugs in clone code. I find it not work well for the following java file. I set
MIN_TOKENS='15' STRIDE='2' SIMILARITY='0.8' .
According to the FSE 07 it is supposed to find out the bug.
The bug line is:
cmp = lhsType.compareTo(lhsType);
if (cmp != 0)
return cmp;
it looks similar several line ahead:
cmp = lhsName.compareTo(rhsName);
if (cmp != 0)
return cmp;
Can anyone help me?
public class VersionInsensitiveBugComparator implements WarningComparator {
private ClassNameRewriter classNameRewriter = IdentityClassNameRewriter.instance();
private boolean exactBugPatternMatch = true;
private boolean comparePriorities = false;
public VersionInsensitiveBugComparator() {
}
public void setClassNameRewriter(ClassNameRewriter classNameRewriter) {
this.classNameRewriter = classNameRewriter;
}
public void setComparePriorities(boolean b) {
comparePriorities = b;
}
/**
* Wrapper for BugAnnotation iterators, which filters out
* annotations we don't care about.
*/
private class FilteringAnnotationIterator implements Iterator<BugAnnotation> {
private Iterator<BugAnnotation> iter;
private BugAnnotation next;
public FilteringAnnotationIterator(Iterator<BugAnnotation> iter) {
this.iter = iter;
this.next = null;
}
public boolean hasNext() {
findNext();
return next != null;
}
public BugAnnotation next() {
findNext();
if (next == null)
throw new NoSuchElementException();
BugAnnotation result = next;
next = null;
return result;
}
public void remove() {
throw new UnsupportedOperationException();
}
private void findNext() {
while (next == null) {
if (!iter.hasNext())
break;
BugAnnotation candidate = iter.next();
if (!isBoring(candidate)) {
next = candidate;
break;
}
}
}
}
private boolean isBoring(BugAnnotation annotation) {
return !annotation.isSignificant();
}
private static int compareNullElements(Object a, Object b) {
if (a != null)
return 1;
else if (b != null)
return -1;
else
return 0;
}
private static String getCode(String pattern) {
int sep = pattern.indexOf('_');
if (sep < 0)
return "";
return pattern.substring(0, sep);
}
public int compare(BugInstance lhs, BugInstance rhs) {
// Attributes of BugInstance.
// Compare abbreviation
// Compare class and method annotations (ignoring line numbers).
// Compare field annotations.
int cmp;
BugPattern lhsPattern = lhs.getBugPattern();
BugPattern rhsPattern = rhs.getBugPattern();
if (lhsPattern == null || rhsPattern == null) {
// One of the patterns is missing.
// However, we can still accurately match by abbrev (usually) by comparing
// the part of the type before the first '_' character.
// This is almost always equivalent to the abbrev.
String lhsCode = getCode(lhs.getType());
String rhsCode = getCode(rhs.getType());
if ((cmp = lhsCode.compareTo(rhsCode)) != 0) {
return cmp;
}
} else {
// Compare by abbrev instead of type. The specific bug type can change
// (e.g., "definitely null" to "null on simple path"). Also, we often
// change bug pattern types from one version of FindBugs to the next.
//
// Source line and field name are still matched precisely, so this shouldn't
// cause loss of precision.
if ((cmp = lhsPattern.getAbbrev().compareTo(rhsPattern.getAbbrev())) != 0)
return cmp;
if (isExactBugPatternMatch() && (cmp = lhsPattern.getType().compareTo(rhsPattern.getType())) != 0)
return cmp;
}
if (comparePriorities) {
cmp = lhs.getPriority() - rhs.getPriority();
if (cmp != 0) return cmp;
}
Iterator<BugAnnotation> lhsIter = new FilteringAnnotationIterator(lhs.annotationIterator());
Iterator<BugAnnotation> rhsIter = new FilteringAnnotationIterator(rhs.annotationIterator());
while (lhsIter.hasNext() && rhsIter.hasNext()) {
BugAnnotation lhsAnnotation = lhsIter.next();
BugAnnotation rhsAnnotation = rhsIter.next();
// Different annotation types obviously cannot be equal,
// so just compare by class name.
if (lhsAnnotation.getClass() != rhsAnnotation.getClass())
return lhsAnnotation.getClass().getName().compareTo(rhsAnnotation.getClass().getName());
if (lhsAnnotation.getClass() == ClassAnnotation.class) {
// ClassAnnotations should have their class names rewritten to
// handle moved and renamed classes.
String lhsClassName = classNameRewriter.rewriteClassName(
((ClassAnnotation)lhsAnnotation).getClassName());
String rhsClassName = classNameRewriter.rewriteClassName(
((ClassAnnotation)rhsAnnotation).getClassName());
cmp = lhsClassName.compareTo(rhsClassName);
if (cmp != 0)
return cmp;
} else if(lhsAnnotation.getClass() == MethodAnnotation.class ) {
// Rewrite class names in MethodAnnotations
MethodAnnotation lhsMethod = ClassNameRewriterUtil.convertMethodAnnotation(
classNameRewriter, (MethodAnnotation) lhsAnnotation);
MethodAnnotation rhsMethod = ClassNameRewriterUtil.convertMethodAnnotation(
classNameRewriter, (MethodAnnotation) rhsAnnotation);
cmp = lhsMethod.compareTo(rhsMethod);
if (cmp != 0)
return cmp;
} else if(lhsAnnotation.getClass() == FieldAnnotation.class) {
// Rewrite class names in FieldAnnotations
FieldAnnotation lhsField = ClassNameRewriterUtil.convertFieldAnnotation(
classNameRewriter, (FieldAnnotation) lhsAnnotation);
FieldAnnotation rhsField = ClassNameRewriterUtil.convertFieldAnnotation(
classNameRewriter, (FieldAnnotation) rhsAnnotation);
cmp = lhsField.compareTo(rhsField);
if (cmp != 0)
return cmp;
} else if(lhsAnnotation.getClass() == StringAnnotation.class) {
// Rewrite class names in FieldAnnotations
String lhsString = ((StringAnnotation)lhsAnnotation).getValue();
String rhsString = ((StringAnnotation)rhsAnnotation).getValue();
cmp = lhsString.compareTo(rhsString);
if (cmp != 0)
return cmp;
} else if(lhsAnnotation.getClass() == LocalVariableAnnotation.class) {
// Rewrite class names in FieldAnnotations
String lhsName = ((LocalVariableAnnotation)lhsAnnotation).getName();
String rhsName = ((LocalVariableAnnotation)rhsAnnotation).getName();
if (lhsName.equals("?") && rhsName.equals("?"))
continue;
cmp = lhsName.compareTo(rhsName);
if (cmp != 0)
return cmp;
} else if(lhsAnnotation.getClass() == TypeAnnotation.class) {
// Rewrite class names in FieldAnnotations
String lhsType = ((TypeAnnotation)lhsAnnotation).getTypeDescriptor();
String rhsType = ((TypeAnnotation)rhsAnnotation).getTypeDescriptor();
lhsType = ClassNameRewriterUtil.rewriteSignature(classNameRewriter, lhsType);
rhsType = ClassNameRewriterUtil.rewriteSignature(classNameRewriter, rhsType);
cmp = lhsType.compareTo(lhsType);
if (cmp != 0)
return cmp;
} else if(lhsAnnotation.getClass() == IntAnnotation.class) {
// Rewrite class names in FieldAnnotations
int lhsValue = ((IntAnnotation)lhsAnnotation).getValue();
int rhsValue = ((IntAnnotation)rhsAnnotation).getValue();
cmp = lhsValue - rhsValue;
if (cmp != 0)
return cmp;
} else if (isBoring(lhsAnnotation)) {
throw new IllegalStateException("Impossible");
} else
throw new IllegalStateException("Unknown annotation type: " + lhsAnnotation.getClass().getName());
}
if (rhsIter.hasNext())
return -1;
else if (lhsIter.hasNext())
return 1;
else
return 0;
}
/**
* @param exactBugPatternMatch The exactBugPatternMatch to set.
*/
public void setExactBugPatternMatch(boolean exactBugPatternMatch) {
this.exactBugPatternMatch = exactBugPatternMatch;
}
/**
* @return Returns the exactBugPatternMatch.
*/
public boolean isExactBugPatternMatch() {
return exactBugPatternMatch;
}
are you looking for clone-related bugs? Then need to run additional steps for bugs, and to reduce false alarms, better to use larger SIMILARITY, say 1.0 or 0.99.
Recently, I try deckard to find bugs in clone code. I find it not work well for the following java file. I set MIN_TOKENS='15' STRIDE='2' SIMILARITY='0.8' . According to the FSE 07 it is supposed to find out the bug. The bug line is: cmp = lhsType.compareTo(lhsType); if (cmp != 0) return cmp; it looks similar several line ahead: cmp = lhsName.compareTo(rhsName); if (cmp != 0) return cmp; Can anyone help me?
public class VersionInsensitiveBugComparator implements WarningComparator {
}