aboutsummaryrefslogtreecommitdiff
path: root/org.jacoco.report/src
diff options
context:
space:
mode:
authorMarc R. Hoffmann <hoffmann@mountainminds.com>2013-03-20 11:55:53 +0100
committerMarc R. Hoffmann <hoffmann@mountainminds.com>2013-05-23 22:21:25 +0200
commit55fae171b754e20062fae7cdb2d5feae8ee54017 (patch)
tree5dfac8aae54da8cb7585f63e6433caf75ccd7531 /org.jacoco.report/src
parentccbbc428f5bad06f43ae6c42f9691a1c9f5a2f73 (diff)
downloadjacoco-55fae171b754e20062fae7cdb2d5feae8ee54017.tar.gz
New coverage check implementation.
New report APIs to check coverage, support for coverage checks in Ant, rework Maven check goal implementation based on new APIs.
Diffstat (limited to 'org.jacoco.report/src')
-rw-r--r--org.jacoco.report/src/org/jacoco/report/ILanguageNames.java16
-rw-r--r--org.jacoco.report/src/org/jacoco/report/JavaNames.java19
-rw-r--r--org.jacoco.report/src/org/jacoco/report/check/BundleChecker.java150
-rw-r--r--org.jacoco.report/src/org/jacoco/report/check/IViolationsOutput.java36
-rw-r--r--org.jacoco.report/src/org/jacoco/report/check/Limit.java194
-rw-r--r--org.jacoco.report/src/org/jacoco/report/check/Rule.java122
-rw-r--r--org.jacoco.report/src/org/jacoco/report/check/RulesChecker.java98
-rw-r--r--org.jacoco.report/src/org/jacoco/report/check/package-info.java16
8 files changed, 650 insertions, 1 deletions
diff --git a/org.jacoco.report/src/org/jacoco/report/ILanguageNames.java b/org.jacoco.report/src/org/jacoco/report/ILanguageNames.java
index fe682696..f45ed644 100644
--- a/org.jacoco.report/src/org/jacoco/report/ILanguageNames.java
+++ b/org.jacoco.report/src/org/jacoco/report/ILanguageNames.java
@@ -67,4 +67,20 @@ public interface ILanguageNames {
public String getMethodName(String vmclassname, String vmmethodname,
String vmdesc, String vmsignature);
+ /**
+ * Calculates the language specific fully qualified name of a method.
+ *
+ * @param vmclassname
+ * vm name of a containing class
+ * @param vmmethodname
+ * vm name of the method
+ * @param vmdesc
+ * vm parameter description of the method
+ * @param vmsignature
+ * vm signature of the method (may be <code>null</code>)
+ * @return language specific notation for the method
+ */
+ public String getQualifiedMethodName(String vmclassname,
+ String vmmethodname, String vmdesc, String vmsignature);
+
}
diff --git a/org.jacoco.report/src/org/jacoco/report/JavaNames.java b/org.jacoco.report/src/org/jacoco/report/JavaNames.java
index 34c33963..e2ec69e1 100644
--- a/org.jacoco.report/src/org/jacoco/report/JavaNames.java
+++ b/org.jacoco.report/src/org/jacoco/report/JavaNames.java
@@ -77,6 +77,19 @@ public class JavaNames implements ILanguageNames {
public String getMethodName(final String vmclassname,
final String vmmethodname, final String vmdesc,
final String vmsignature) {
+ return getMethodName(vmclassname, vmmethodname, vmdesc, false);
+ }
+
+ public String getQualifiedMethodName(final String vmclassname,
+ final String vmmethodname, final String vmdesc,
+ final String vmsignature) {
+ return getQualifiedClassName(vmclassname) + "."
+ + getMethodName(vmclassname, vmmethodname, vmdesc, true);
+ }
+
+ private String getMethodName(final String vmclassname,
+ final String vmmethodname, final String vmdesc,
+ final boolean qualifiedParams) {
if ("<clinit>".equals(vmmethodname)) {
return "static {...}";
}
@@ -99,7 +112,11 @@ public class JavaNames implements ILanguageNames {
} else {
comma = true;
}
- result.append(getShortTypeName(arg));
+ if (qualifiedParams) {
+ result.append(getQualifiedClassName(arg.getClassName()));
+ } else {
+ result.append(getShortTypeName(arg));
+ }
}
result.append(')');
return result.toString();
diff --git a/org.jacoco.report/src/org/jacoco/report/check/BundleChecker.java b/org.jacoco.report/src/org/jacoco/report/check/BundleChecker.java
new file mode 100644
index 00000000..7f2cfc8f
--- /dev/null
+++ b/org.jacoco.report/src/org/jacoco/report/check/BundleChecker.java
@@ -0,0 +1,150 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Mountainminds GmbH & Co. KG and Contributors
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ *******************************************************************************/
+package org.jacoco.report.check;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.jacoco.core.analysis.IBundleCoverage;
+import org.jacoco.core.analysis.IClassCoverage;
+import org.jacoco.core.analysis.ICoverageNode;
+import org.jacoco.core.analysis.IMethodCoverage;
+import org.jacoco.core.analysis.IPackageCoverage;
+import org.jacoco.core.analysis.ISourceFileCoverage;
+import org.jacoco.report.ILanguageNames;
+
+/**
+ * Internal class to check a list of rules against a {@link IBundleCoverage}
+ * instance.
+ */
+class BundleChecker {
+
+ private final ILanguageNames names;
+ private final IViolationsOutput output;
+
+ private final Collection<Rule> bundleRules;
+ private final Collection<Rule> packageRules;
+ private final Collection<Rule> classRules;
+ private final ArrayList<Rule> sourceFileRules;
+ private final Collection<Rule> methodRules;
+
+ private final boolean traversePackages;
+ private final boolean traverseClasses;
+ private final boolean traverseSourceFiles;
+ private final boolean traverseMethods;
+
+ public BundleChecker(final Collection<Rule> rules,
+ final ILanguageNames names, final IViolationsOutput output) {
+ this.names = names;
+ this.output = output;
+ this.bundleRules = new ArrayList<Rule>();
+ this.packageRules = new ArrayList<Rule>();
+ this.classRules = new ArrayList<Rule>();
+ this.sourceFileRules = new ArrayList<Rule>();
+ this.methodRules = new ArrayList<Rule>();
+ for (final Rule rule : rules) {
+ switch (rule.getElement()) {
+ case BUNDLE:
+ bundleRules.add(rule);
+ break;
+ case PACKAGE:
+ packageRules.add(rule);
+ break;
+ case CLASS:
+ classRules.add(rule);
+ break;
+ case SOURCEFILE:
+ sourceFileRules.add(rule);
+ break;
+ case METHOD:
+ methodRules.add(rule);
+ break;
+ }
+ }
+ traverseMethods = !methodRules.isEmpty();
+ traverseClasses = !classRules.isEmpty() || traverseMethods;
+ traverseSourceFiles = !sourceFileRules.isEmpty();
+ traversePackages = !packageRules.isEmpty() || traverseClasses
+ || traverseSourceFiles;
+ }
+
+ public void checkBundle(final IBundleCoverage bundleCoverage) {
+ final String name = bundleCoverage.getName();
+ checkRules(bundleCoverage, bundleRules, "bundle", name);
+ if (traversePackages) {
+ for (final IPackageCoverage p : bundleCoverage.getPackages()) {
+ check(p);
+ }
+ }
+ }
+
+ private void check(final IPackageCoverage packageCoverage) {
+ final String name = names.getPackageName(packageCoverage.getName());
+ checkRules(packageCoverage, packageRules, "package", name);
+ if (traverseClasses) {
+ for (final IClassCoverage c : packageCoverage.getClasses()) {
+ check(c);
+ }
+ }
+ if (traverseSourceFiles) {
+ for (final ISourceFileCoverage s : packageCoverage.getSourceFiles()) {
+ check(s);
+ }
+ }
+ }
+
+ private void check(final IClassCoverage classCoverage) {
+ final String name = names
+ .getQualifiedClassName(classCoverage.getName());
+ checkRules(classCoverage, classRules, "class", name);
+ if (traverseMethods) {
+ for (final IMethodCoverage m : classCoverage.getMethods()) {
+ check(m, classCoverage.getName());
+ }
+ }
+ }
+
+ private void check(final ISourceFileCoverage sourceFile) {
+ final String name = sourceFile.getPackageName() + "/"
+ + sourceFile.getName();
+ checkRules(sourceFile, sourceFileRules, "source file", name);
+ }
+
+ private void check(final IMethodCoverage method, final String className) {
+ final String name = names.getQualifiedMethodName(className,
+ method.getName(), method.getDesc(), method.getSignature());
+ checkRules(method, methodRules, "method", name);
+ }
+
+ private void checkRules(final ICoverageNode node,
+ final Collection<Rule> rules, final String typename,
+ final String elementname) {
+ for (final Rule rule : rules) {
+ if (rule.matches(elementname)) {
+ for (final Limit limit : rule.getLimits()) {
+ checkLimit(node, typename, elementname, rule, limit);
+ }
+ }
+ }
+ }
+
+ private void checkLimit(final ICoverageNode node, final String elementtype,
+ final String typename, final Rule rule, final Limit limit) {
+ final String message = limit.check(node);
+ if (message != null) {
+ output.onViolation(node, rule, limit, String.format(
+ "Rule violated for %s %s: %s", elementtype, typename,
+ message));
+ }
+ }
+
+}
diff --git a/org.jacoco.report/src/org/jacoco/report/check/IViolationsOutput.java b/org.jacoco.report/src/org/jacoco/report/check/IViolationsOutput.java
new file mode 100644
index 00000000..9167ccc7
--- /dev/null
+++ b/org.jacoco.report/src/org/jacoco/report/check/IViolationsOutput.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Mountainminds GmbH & Co. KG and Contributors
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ *******************************************************************************/
+package org.jacoco.report.check;
+
+import org.jacoco.core.analysis.ICoverageNode;
+
+/**
+ * Call-back interface which is used to report rule violations to.
+ *
+ */
+public interface IViolationsOutput {
+
+ /**
+ * Called for every rule violation.
+ *
+ * @param node
+ * node which violates a rule
+ * @param rule
+ * rule which is violated
+ * @param limit
+ * limit which is violated
+ * @param message
+ * readable message describing this violation
+ */
+ void onViolation(ICoverageNode node, Rule rule, Limit limit, String message);
+
+}
diff --git a/org.jacoco.report/src/org/jacoco/report/check/Limit.java b/org.jacoco.report/src/org/jacoco/report/check/Limit.java
new file mode 100644
index 00000000..8aec0ded
--- /dev/null
+++ b/org.jacoco.report/src/org/jacoco/report/check/Limit.java
@@ -0,0 +1,194 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Mountainminds GmbH & Co. KG and Contributors
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ *******************************************************************************/
+package org.jacoco.report.check;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jacoco.core.analysis.ICounter.CounterValue;
+import org.jacoco.core.analysis.ICoverageNode;
+import org.jacoco.core.analysis.ICoverageNode.CounterEntity;
+
+/**
+ * Descriptor for a limit which is given by a {@link Rule}.
+ */
+public class Limit {
+
+ private static final Map<CounterValue, String> VALUE_NAMES;
+ private static final Map<CounterEntity, String> ENTITY_NAMES;
+
+ static {
+ final Map<CounterValue, String> values = new HashMap<CounterValue, String>();
+ values.put(CounterValue.TOTALCOUNT, "total count");
+ values.put(CounterValue.MISSEDCOUNT, "missed count");
+ values.put(CounterValue.COVEREDCOUNT, "covered count");
+ values.put(CounterValue.MISSEDRATIO, "missed ratio");
+ values.put(CounterValue.COVEREDRATIO, "covered ratio");
+ VALUE_NAMES = Collections.unmodifiableMap(values);
+
+ final Map<CounterEntity, String> entities = new HashMap<CounterEntity, String>();
+ entities.put(CounterEntity.INSTRUCTION, "instructions");
+ entities.put(CounterEntity.BRANCH, "branches");
+ entities.put(CounterEntity.COMPLEXITY, "complexity");
+ entities.put(CounterEntity.LINE, "lines");
+ entities.put(CounterEntity.METHOD, "methods");
+ entities.put(CounterEntity.CLASS, "classes");
+ ENTITY_NAMES = Collections.unmodifiableMap(entities);
+ }
+
+ private CounterEntity entity;
+
+ private CounterValue value;
+
+ private BigDecimal minimum;
+
+ private BigDecimal maximum;
+
+ /**
+ * Creates a new instance with the following defaults:
+ * <ul>
+ * <li>counter entity: {@link CounterEntity#INSTRUCTION}
+ * <li>counter value: {@link CounterValue#COVEREDRATIO}
+ * <li>minimum: no limit
+ * <li>maximum: no limit
+ * </ul>
+ */
+ public Limit() {
+ this.entity = CounterEntity.INSTRUCTION;
+ this.value = CounterValue.COVEREDRATIO;
+ }
+
+ /**
+ * @return the configured counter entity to check
+ */
+ public CounterEntity getEntity() {
+ return entity;
+ }
+
+ /**
+ * Sets the counter entity to check.
+ *
+ * @param entity
+ * counter entity to check
+ */
+ public void setCounter(final CounterEntity entity) {
+ this.entity = entity;
+ }
+
+ /**
+ * @return the configured value to check
+ */
+ public CounterValue getValue() {
+ return value;
+ }
+
+ /**
+ * Sets the value to check.
+ *
+ * @param value
+ * value to check
+ */
+ public void setValue(final CounterValue value) {
+ this.value = value;
+ }
+
+ /**
+ * @return configured minimum value, or <code>null</code> if no minimum is
+ * given
+ */
+ public BigDecimal getMinimum() {
+ return minimum;
+ }
+
+ /**
+ * Sets allowed minimum value. Coverage ratios are given in the range from
+ * 0.0 to 1.0.
+ *
+ * @param minimum
+ * allowed minimum or <code>null</code>, if no minimum should be
+ * checked
+ */
+ public void setMinimum(final BigDecimal minimum) {
+ this.minimum = minimum;
+ }
+
+ /**
+ * Sets allowed minimum value as String representation.
+ *
+ * @param minimum
+ * allowed minimum or <code>null</code>, if no minimum should be
+ * checked
+ * @see Limit#setMinimum(BigDecimal)
+ */
+ public void setMinimum(final String minimum) {
+ setMinimum(minimum == null ? null : new BigDecimal(minimum));
+ }
+
+ /**
+ * @return configured maximum value, or <code>null</code> if no maximum is
+ * given
+ */
+ public BigDecimal getMaximum() {
+ return maximum;
+ }
+
+ /**
+ * Sets allowed maximum value as String representation.
+ *
+ * @param maximum
+ * allowed maximum or <code>null</code>, if no maximum should be
+ * checked
+ * @see #setMaximum(BigDecimal)
+ */
+ public void setMaximum(final String maximum) {
+ setMaximum(maximum == null ? null : new BigDecimal(maximum));
+ }
+
+ /**
+ * Sets allowed maximum value. Coverage ratios are given in the range from
+ * 0.0 to 1.0.
+ *
+ * @param maximum
+ * allowed maximum or <code>null</code>, if no maximum should be
+ * checked
+ */
+ public void setMaximum(final BigDecimal maximum) {
+ this.maximum = maximum;
+ }
+
+ String check(final ICoverageNode node) {
+ final double d = node.getCounter(entity).getValue(value);
+ if (Double.isNaN(d)) {
+ return null;
+ }
+ final BigDecimal bd = BigDecimal.valueOf(d);
+ if (minimum != null && minimum.compareTo(bd) > 0) {
+ return message("minimum", bd, minimum, RoundingMode.FLOOR);
+ }
+ if (maximum != null && maximum.compareTo(bd) < 0) {
+ return message("maximum", bd, maximum, RoundingMode.CEILING);
+ }
+ return null;
+ }
+
+ private String message(final String minmax, final BigDecimal v,
+ final BigDecimal ref, final RoundingMode mode) {
+ final BigDecimal rounded = v.setScale(ref.scale(), mode);
+ return String.format("%s %s is %s, but expected %s is %s",
+ ENTITY_NAMES.get(entity), VALUE_NAMES.get(value),
+ rounded.toPlainString(), minmax, ref.toPlainString());
+ }
+
+}
diff --git a/org.jacoco.report/src/org/jacoco/report/check/Rule.java b/org.jacoco.report/src/org/jacoco/report/check/Rule.java
new file mode 100644
index 00000000..3dea01e3
--- /dev/null
+++ b/org.jacoco.report/src/org/jacoco/report/check/Rule.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Mountainminds GmbH & Co. KG and Contributors
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ *******************************************************************************/
+package org.jacoco.report.check;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jacoco.core.analysis.ICoverageNode.ElementType;
+import org.jacoco.core.runtime.WildcardMatcher;
+
+/**
+ * A rule applies for a certain element type and can define any number of limits
+ * for all elements of this type.
+ */
+public final class Rule {
+
+ private ElementType element;
+ private String includes;
+ private String excludes;
+ private List<Limit> limits;
+
+ private WildcardMatcher includesMatcher;
+ private WildcardMatcher excludesMatcher;
+
+ /**
+ * Creates a new Rule without limits.
+ */
+ public Rule() {
+ this.element = ElementType.BUNDLE;
+ this.limits = new ArrayList<Limit>();
+ this.setIncludes("*");
+ this.setExcludes("");
+ }
+
+ /**
+ * @return element type this rule applies to
+ */
+ public ElementType getElement() {
+ return element;
+ }
+
+ /**
+ * @param elementType
+ * element type this rule applies to
+ */
+ public void setElement(final ElementType elementType) {
+ this.element = elementType;
+ }
+
+ /**
+ * @return includes pattern
+ */
+ public String getIncludes() {
+ return includes;
+ }
+
+ /**
+ * @param includes
+ * includes pattern
+ */
+ public void setIncludes(final String includes) {
+ this.includes = includes;
+ this.includesMatcher = new WildcardMatcher(includes);
+ }
+
+ /**
+ * @return excludes pattern
+ */
+ public String getExcludes() {
+ return excludes;
+ }
+
+ /**
+ *
+ * @param excludes
+ * excludes patterns
+ */
+ public void setExcludes(final String excludes) {
+ this.excludes = excludes;
+ this.excludesMatcher = new WildcardMatcher(excludes);
+ }
+
+ /**
+ * @return list of {@link Limit}s configured for this rule
+ */
+ public List<Limit> getLimits() {
+ return limits;
+ }
+
+ /**
+ * @param limits
+ * list of {@link Limit}s configured for this rule
+ */
+ public void setLimits(final List<Limit> limits) {
+ this.limits = limits;
+ }
+
+ /**
+ * Creates and adds a new {@link Limit}.
+ *
+ * @return creates {@link Limit}
+ */
+ public Limit createLimit() {
+ final Limit limit = new Limit();
+ this.limits.add(limit);
+ return limit;
+ }
+
+ boolean matches(final String name) {
+ return includesMatcher.matches(name) && !excludesMatcher.matches(name);
+ }
+
+}
diff --git a/org.jacoco.report/src/org/jacoco/report/check/RulesChecker.java b/org.jacoco.report/src/org/jacoco/report/check/RulesChecker.java
new file mode 100644
index 00000000..ddcb7c75
--- /dev/null
+++ b/org.jacoco.report/src/org/jacoco/report/check/RulesChecker.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Mountainminds GmbH & Co. KG and Contributors
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ *******************************************************************************/
+package org.jacoco.report.check;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.jacoco.core.analysis.IBundleCoverage;
+import org.jacoco.core.data.ExecutionData;
+import org.jacoco.core.data.SessionInfo;
+import org.jacoco.report.ILanguageNames;
+import org.jacoco.report.IReportGroupVisitor;
+import org.jacoco.report.IReportVisitor;
+import org.jacoco.report.ISourceFileLocator;
+import org.jacoco.report.JavaNames;
+
+/**
+ * Formatter which checks a set of given rules and reports violations to a
+ * {@link IViolationsOutput} instance.
+ */
+public class RulesChecker {
+
+ private List<Rule> rules;
+ private ILanguageNames languageNames;
+
+ /**
+ * New formatter instance.
+ */
+ public RulesChecker() {
+ this.rules = new ArrayList<Rule>();
+ this.setLanguageNames(new JavaNames());
+ }
+
+ /**
+ * Sets the rules to check by this formatter.
+ *
+ * @param rules
+ * rules to check
+ */
+ public void setRules(final List<Rule> rules) {
+ this.rules = rules;
+ }
+
+ /**
+ * Sets the implementation for language name display for message formatting.
+ * Java language names are defined by default.
+ *
+ * @param languageNames
+ * converter for language specific names
+ */
+ public void setLanguageNames(final ILanguageNames languageNames) {
+ this.languageNames = languageNames;
+ }
+
+ /**
+ * Creates a new visitor to process the configured checks.
+ *
+ * @param output
+ * call-back to report violations to
+ * @return visitor to emit the report data to
+ */
+ public IReportVisitor createVisitor(final IViolationsOutput output) {
+ final BundleChecker bundleChecker = new BundleChecker(rules,
+ languageNames, output);
+ return new IReportVisitor() {
+
+ public IReportGroupVisitor visitGroup(final String name)
+ throws IOException {
+ return this;
+ }
+
+ public void visitBundle(final IBundleCoverage bundle,
+ final ISourceFileLocator locator) throws IOException {
+ bundleChecker.checkBundle(bundle);
+ }
+
+ public void visitInfo(final List<SessionInfo> sessionInfos,
+ final Collection<ExecutionData> executionData)
+ throws IOException {
+ }
+
+ public void visitEnd() throws IOException {
+ }
+ };
+ }
+
+}
diff --git a/org.jacoco.report/src/org/jacoco/report/check/package-info.java b/org.jacoco.report/src/org/jacoco/report/check/package-info.java
new file mode 100644
index 00000000..e0fe96a8
--- /dev/null
+++ b/org.jacoco.report/src/org/jacoco/report/check/package-info.java
@@ -0,0 +1,16 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Mountainminds GmbH & Co. KG and Contributors
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ *******************************************************************************/
+
+/**
+ * Rules check implementation.
+ */
+package org.jacoco.report.check; \ No newline at end of file