blob: 6e85b9fe26366f44f50aacc2fecf18c13e8f2262 [file] [log] [blame]
Yue Ganaf3c4122016-12-05 14:36:02 +00001// Copyright 2016 The Bazel Authors. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package com.google.testing.coverage;
16
17import java.util.List;
18import java.util.Map;
19import java.util.TreeMap;
20import org.jacoco.core.analysis.Analyzer;
21import org.jacoco.core.data.ExecutionData;
22import org.jacoco.core.data.ExecutionDataStore;
23import org.jacoco.core.internal.data.CRC64;
24import org.jacoco.core.internal.flow.ClassProbesAdapter;
25import org.objectweb.asm.ClassReader;
26
27/**
28 * Analyzer that process the branch coverage detail information.
29 *
30 * <p>Reuse the Analyzer class from Jacoco to avoid duplicating the content detection logic.
31 * Override the main {@code Analyzer.analyzeClass} method which does the main work.
32 */
33public class BranchDetailAnalyzer extends Analyzer {
34
35 private final ExecutionDataStore executionData;
36 private final Map<String, BranchCoverageDetail> branchDetails;
37
38 public BranchDetailAnalyzer(final ExecutionDataStore executionData) {
39 super(executionData, null);
40 this.executionData = executionData;
41 this.branchDetails = new TreeMap<String, BranchCoverageDetail>();
42 }
43
44 @Override
45 public void analyzeClass(final ClassReader reader) {
46 final Map<Integer, BranchExp> lineToBranchExp = mapProbes(reader);
47
48 long classid = CRC64.checksum(reader.b);
49 ExecutionData classData = executionData.get(classid);
50 if (classData == null) {
51 return;
52 }
53 boolean[] probes = classData.getProbes();
54
55 BranchCoverageDetail detail = new BranchCoverageDetail();
56
57 for (Map.Entry<Integer, BranchExp> entry : lineToBranchExp.entrySet()) {
58 int line = entry.getKey();
59 BranchExp branchExp = entry.getValue();
60 List<CovExp> branches = branchExp.getBranches();
61
62 detail.setBranches(line, branches.size());
63 for (int branchIdx = 0; branchIdx < branches.size(); branchIdx++) {
64 if (branches.get(branchIdx).eval(probes)) {
65 detail.setTakenBit(line, branchIdx);
66 }
67 }
68 }
69 if (detail.linesWithBranches().size() > 0) {
70 branchDetails.put(reader.getClassName(), detail);
71 }
72 }
73
74 // Generate the line to probeExp map so that we can evaluate the coverage.
75 private Map<Integer, BranchExp> mapProbes(final ClassReader reader) {
76 final ClassProbesMapper mapper = new ClassProbesMapper();
77 final ClassProbesAdapter adapter = new ClassProbesAdapter(mapper, false);
78 reader.accept(adapter, 0);
79
80 return mapper.result();
81 }
82
83 public Map<String, BranchCoverageDetail> getBranchDetails() {
84 return branchDetails;
85 }
86}