}
ClassData diffClasses(ClassData larger, ClassData smaller) {
ClassData result = new ClassData(larger.getName());
for (Object o : larger.getLines()) {
LineData lld = (LineData) o;
long afterHits = lld.getHits();
long prevHits = 0;
long prevConditions = 0;
if (smaller != null) {
LineData sld = smaller.getLineCoverage(lld.getLineNumber());
if (sld != null) {
prevHits = sld.getHits();
prevConditions = sld.getConditionSize();
}
}
int diffHits = (int) (afterHits - prevHits);
result.addLine(lld.getLineNumber(), lld.getMethodName(),
lld.getMethodDescriptor());
if (diffHits > 0) {
result.touch(lld.getLineNumber(), diffHits);
}
if (diffHits < 0) {
errors.add("Coverage decreased on line " + lld.getLineNumber()
+ " of " + larger.getName());
}
if (prevConditions > lld.getConditionSize()) {
errors.add("Jump or Switch disappeared on line "
+ lld.getLineNumber() + " of " + larger.getName());
}
for (int i = 0; i < lld.getConditionSize(); i++) {
Object cd = lld.getConditionData(i);
if (cd instanceof JumpData) {
JumpData ljd = (JumpData) cd;
result.addLineJump(lld.getLineNumber(), i);
long prevTrue = 0;
long prevFalse = 0;
if (smaller != null) {
LineData sld = smaller.getLineCoverage(lld
.getLineNumber());
if (sld != null) {
JumpData sjd = (JumpData) sld.getConditionData(i);
if (sjd != null) {
prevTrue = sjd.getTrueHits();
prevFalse = sjd.getFalseHits();
} else {
errors.add("Somehow, JumpData null at condition "
+ i + " on line " + lld.getLineNumber());
}
}
}
long diffTrueHits = ljd.getTrueHits() - prevTrue;
long diffFalseHits = ljd.getFalseHits() - prevFalse;
if (diffTrueHits > 0) {
result.touchJump(lld.getLineNumber(), i, true,
(int) diffTrueHits);
}
if (diffFalseHits > 0) {
result.touchJump(lld.getLineNumber(), i, false,
(int) diffFalseHits);
}
if (diffFalseHits < 0 || diffTrueHits < 0) {
errors.add("Jump coverage on " + result.getName() + ":"
+ lld.getLineNumber() + ":" + i + " decreased:"
+ "true from " + prevTrue + " by "
+ diffTrueHits + ", false from " + prevFalse
+ " by " + diffFalseHits);
}
} else if (cd instanceof SwitchData) {
SwitchData lsd = (SwitchData) cd;
result.addLineSwitch(lld.getLineNumber(), i, 0, 0, lsd.getMaxBranches());
long[] prevBranchHits = new long[lsd
.getNumberOfValidBranches() - 1];
long prevDefaultHits = 0;
if (smaller != null) {
LineData sld = smaller.getLineCoverage(lld
.getLineNumber());
if (sld != null) {
SwitchData ssd = (SwitchData) sld
.getConditionData(i);
if (ssd != null) {
for (int j = 0; j < prevBranchHits.length; j++) {
// returns -1 on an error condition.
// probably never happens in normal