blob: 7ccd843d3ce96ef0e27967577d519a9a1d560660 [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;
Lukacs Berki22b79d32017-01-05 08:59:22 +000021import org.jacoco.core.analysis.IClassCoverage;
22import org.jacoco.core.analysis.ICoverageVisitor;
Yue Ganaf3c4122016-12-05 14:36:02 +000023import org.jacoco.core.data.ExecutionData;
24import org.jacoco.core.data.ExecutionDataStore;
25import org.jacoco.core.internal.data.CRC64;
26import org.jacoco.core.internal.flow.ClassProbesAdapter;
27import org.objectweb.asm.ClassReader;
28
29/**
30 * Analyzer that process the branch coverage detail information.
31 *
32 * <p>Reuse the Analyzer class from Jacoco to avoid duplicating the content detection logic.
33 * Override the main {@code Analyzer.analyzeClass} method which does the main work.
34 */
35public class BranchDetailAnalyzer extends Analyzer {
36
37 private final ExecutionDataStore executionData;
38 private final Map<String, BranchCoverageDetail> branchDetails;
39
40 public BranchDetailAnalyzer(final ExecutionDataStore executionData) {
Lukacs Berki22b79d32017-01-05 08:59:22 +000041 super(executionData, new ICoverageVisitor() {
42 @Override
43 public void visitCoverage(IClassCoverage coverage) {
44 }
45 });
46
Yue Ganaf3c4122016-12-05 14:36:02 +000047 this.executionData = executionData;
48 this.branchDetails = new TreeMap<String, BranchCoverageDetail>();
49 }
50
51 @Override
52 public void analyzeClass(final ClassReader reader) {
53 final Map<Integer, BranchExp> lineToBranchExp = mapProbes(reader);
54
55 long classid = CRC64.checksum(reader.b);
56 ExecutionData classData = executionData.get(classid);
57 if (classData == null) {
58 return;
59 }
60 boolean[] probes = classData.getProbes();
61
62 BranchCoverageDetail detail = new BranchCoverageDetail();
63
64 for (Map.Entry<Integer, BranchExp> entry : lineToBranchExp.entrySet()) {
65 int line = entry.getKey();
66 BranchExp branchExp = entry.getValue();
67 List<CovExp> branches = branchExp.getBranches();
68
69 detail.setBranches(line, branches.size());
70 for (int branchIdx = 0; branchIdx < branches.size(); branchIdx++) {
71 if (branches.get(branchIdx).eval(probes)) {
72 detail.setTakenBit(line, branchIdx);
73 }
74 }
75 }
76 if (detail.linesWithBranches().size() > 0) {
77 branchDetails.put(reader.getClassName(), detail);
78 }
79 }
80
81 // Generate the line to probeExp map so that we can evaluate the coverage.
82 private Map<Integer, BranchExp> mapProbes(final ClassReader reader) {
83 final ClassProbesMapper mapper = new ClassProbesMapper();
84 final ClassProbesAdapter adapter = new ClassProbesAdapter(mapper, false);
85 reader.accept(adapter, 0);
86
87 return mapper.result();
88 }
89
90 public Map<String, BranchCoverageDetail> getBranchDetails() {
91 return branchDetails;
92 }
93}