package org.pitest.coverage.execute; import java.util.Collection; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import org.pitest.classinfo.ClassName; import org.pitest.coverage.BlockLocation; import org.pitest.coverage.CoverageResult; import org.pitest.functional.SideEffect1; import org.pitest.mutationtest.engine.Location; import org.pitest.mutationtest.engine.MethodName; import org.pitest.testapi.Description; import org.pitest.util.Id; import org.pitest.util.ReceiveStrategy; import org.pitest.util.SafeDataInputStream; import sun.pitest.CodeCoverageStore; final class Receive implements ReceiveStrategy { private final Map<Integer, ClassName> classIdToName = new ConcurrentHashMap<Integer, ClassName>(); private final Map<Long, BlockLocation> probeToBlock = new ConcurrentHashMap<Long, BlockLocation>(); private final SideEffect1<CoverageResult> handler; Receive(final SideEffect1<CoverageResult> handler) { this.handler = handler; } @Override public void apply(final byte control, final SafeDataInputStream is) { switch (control) { case Id.CLAZZ: final int id = is.readInt(); final String name = is.readString(); this.classIdToName.put(id, ClassName.fromString(name)); break; case Id.PROBES: handleProbes(is); break; case Id.OUTCOME: handleTestEnd(is); break; case Id.DONE: // nothing to do ? } } private void handleProbes(final SafeDataInputStream is) { final int classId = is.readInt(); final String methodName = is.readString(); final String methodSig = is.readString(); final int first = is.readInt(); final int last = is.readInt(); Location loc = Location.location(this.classIdToName.get(classId), MethodName.fromString(methodName), methodSig); for (int i = first; i != (last + 1); i++) { // nb, convert from classwide id to method scoped index within // BlockLocation this.probeToBlock.put(CodeCoverageStore.encode(classId, i), new BlockLocation(loc, i - first)); } } private void handleTestEnd(final SafeDataInputStream is) { final Description d = is.read(Description.class); final int numberOfResults = is.readInt(); final Set<BlockLocation> hits = new HashSet<BlockLocation>(numberOfResults); for (int i = 0; i != numberOfResults; i++) { readProbeHit(is, hits); } this.handler.apply(createCoverageResult(is, d, hits)); } private void readProbeHit(final SafeDataInputStream is, final Set<BlockLocation> hits) { final long encoded = is.readLong(); BlockLocation location = probeToBlock(encoded); hits.add(location); } private BlockLocation probeToBlock(long encoded) { return this.probeToBlock.get(encoded); } private CoverageResult createCoverageResult(final SafeDataInputStream is, final Description d, Collection<BlockLocation> visitedBlocks) { final boolean isGreen = is.readBoolean(); final int executionTime = is.readInt(); final CoverageResult cr = new CoverageResult(d, executionTime, isGreen, visitedBlocks); return cr; } }