aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassAnalyzerTest.java44
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/test/validation/EnumImplicitMethodsTest.java39
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/test/validation/targets/EnumImplicitMethods.java48
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassAnalyzer.java22
-rw-r--r--org.jacoco.doc/docroot/doc/changes.html7
5 files changed, 158 insertions, 2 deletions
diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassAnalyzerTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassAnalyzerTest.java
index d4e39997..9c8e6df8 100644
--- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassAnalyzerTest.java
+++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassAnalyzerTest.java
@@ -87,4 +87,48 @@ public class ClassAnalyzerTest {
assertEquals(1, coverage.getMethods().size());
}
+ @Test
+ public void testMethodFilter_EnumValues() {
+ analyzer.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "Foo", null,
+ "java/lang/Enum", null);
+ final MethodProbesVisitor mv = analyzer.visitMethod(0, "values",
+ "()[LFoo;", null, null);
+ assertNull(mv);
+ assertTrue(coverage.getMethods().isEmpty());
+ }
+
+ @Test
+ public void testMethodFilter_EnumNonValues() {
+ analyzer.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "Foo", null,
+ "java/lang/Enum", null);
+ final MethodProbesVisitor mv = analyzer.visitMethod(0, "values", "()V",
+ null, null);
+ mv.visitCode();
+ mv.visitInsn(Opcodes.RETURN);
+ mv.visitEnd();
+ assertEquals(1, coverage.getMethods().size());
+ }
+
+ @Test
+ public void testMethodFilter_EnumValueOf() {
+ analyzer.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "Foo", null,
+ "java/lang/Enum", null);
+ final MethodProbesVisitor mv = analyzer.visitMethod(0, "valueOf",
+ "(Ljava/lang/String;)LFoo;", null, null);
+ assertNull(mv);
+ assertTrue(coverage.getMethods().isEmpty());
+ }
+
+ @Test
+ public void testMethodFilter_EnumNonValueOf() {
+ analyzer.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "Foo", null,
+ "java/lang/Enum", null);
+ final MethodProbesVisitor mv = analyzer.visitMethod(0, "valueOf", "()V",
+ null, null);
+ mv.visitCode();
+ mv.visitInsn(Opcodes.RETURN);
+ mv.visitEnd();
+ assertEquals(1, coverage.getMethods().size());
+ }
+
}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/validation/EnumImplicitMethodsTest.java b/org.jacoco.core.test/src/org/jacoco/core/test/validation/EnumImplicitMethodsTest.java
new file mode 100644
index 00000000..ddc1da12
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/test/validation/EnumImplicitMethodsTest.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2017 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:
+ * Evgeny Mandrikov - initial API and implementation
+ *
+ *******************************************************************************/
+package org.jacoco.core.test.validation;
+
+import org.jacoco.core.analysis.ICounter;
+import org.jacoco.core.test.validation.targets.EnumImplicitMethods;
+import org.junit.Test;
+
+/**
+ * Test of an implicit methods and static initializer in enums.
+ */
+public class EnumImplicitMethodsTest extends ValidationTestBase {
+
+ public EnumImplicitMethodsTest() {
+ super(EnumImplicitMethods.class);
+ }
+
+ @Test
+ public void testCoverageResult() {
+ assertLine("classdef", ICounter.FULLY_COVERED);
+ assertLine("customValueOfMethod", ICounter.NOT_COVERED);
+ assertLine("customValuesMethod", ICounter.NOT_COVERED);
+
+ assertLine("const", ICounter.PARTLY_COVERED);
+ assertLine("staticblock", ICounter.FULLY_COVERED);
+ assertLine("super", ICounter.FULLY_COVERED);
+ assertLine("constructor", ICounter.FULLY_COVERED);
+ }
+
+}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/validation/targets/EnumImplicitMethods.java b/org.jacoco.core.test/src/org/jacoco/core/test/validation/targets/EnumImplicitMethods.java
new file mode 100644
index 00000000..aaa5e987
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/test/validation/targets/EnumImplicitMethods.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2017 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:
+ * Evgeny Mandrikov - initial API and implementation
+ *
+ *******************************************************************************/
+package org.jacoco.core.test.validation.targets;
+
+public enum EnumImplicitMethods { // $line-classdef$
+
+ CONST(Stubs.f() ? new Object() : new Object()); // $line-const$
+
+ static {
+ } // $line-staticblock$
+
+ /**
+ * Unlike in {@link Target07 regular classes}, even if enum has explicit
+ * constructor, {@code clinit} method in any case has a reference to the
+ * line of enum definition.
+ */
+ EnumImplicitMethods(Object o) { // $line-super$
+ } // $line-constructor$
+
+ /**
+ * This method should not be excluded from analysis unlike implicitly
+ * created {@link #valueOf(String)} method that refers to the line of enum
+ * definition.
+ */
+ public void valueOf() {
+ } // $line-customValueOfMethod$
+
+ /**
+ * This method should not be excluded from analysis unlike implicitly
+ * created {@link #values()} method that refers to the line of enum
+ * definition.
+ */
+ public void values(Object o) {
+ } // $line-customValuesMethod$
+
+ public static void main(String[] args) {
+ }
+
+}
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassAnalyzer.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassAnalyzer.java
index f32ef8db..06e13248 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassAnalyzer.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassAnalyzer.java
@@ -64,7 +64,8 @@ public class ClassAnalyzer extends ClassProbesVisitor {
InstrSupport.assertNotInstrumented(name, coverage.getName());
- if (isMethodFiltered(access, name)) {
+ if (isMethodFiltered(coverage.getName(), coverage.getSuperName(),
+ access, name, desc)) {
return null;
}
@@ -82,8 +83,25 @@ public class ClassAnalyzer extends ClassProbesVisitor {
};
}
+ /**
+ * @return <code>true</code> if method should not be analyzed
+ */
// TODO: Use filter hook in future
- private boolean isMethodFiltered(final int access, final String name) {
+ private boolean isMethodFiltered(final String className,
+ final String superClassName, final int access, final String name,
+ final String desc) {
+ if ("java/lang/Enum".equals(superClassName)) {
+ // filter out methods that compiler creates for enums
+ if ("values".equals(name)
+ && ("()[L" + className + ";").equals(desc)) {
+ return true;
+ }
+ if ("valueOf".equals(name)
+ && ("(Ljava/lang/String;)L" + className + ";")
+ .equals(desc)) {
+ return true;
+ }
+ }
return (access & Opcodes.ACC_SYNTHETIC) != 0
&& !name.startsWith("lambda$");
}
diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html
index 75ddce0b..34b36b23 100644
--- a/org.jacoco.doc/docroot/doc/changes.html
+++ b/org.jacoco.doc/docroot/doc/changes.html
@@ -20,6 +20,13 @@
<h2>Snapshot Build @qualified.bundle.version@ (@build.date@)</h2>
+<h3>New Features</h3>
+<ul>
+ <li>Exclude from a report enum methods <code>valueOf</code> and <code>values</code>
+ that are created by compiler
+ (GitHub <a href="https://github.com/jacoco/jacoco/issues/491">#491</a>).</li>
+</ul>
+
<h2>Release 0.7.9 (2017/02/05)</h2>
<h3>Fixed Bugs</h3>