Use new filtering API for existing filter of methods in enums (#512)
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 6da24ff..c71e52f 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
@@ -59,48 +59,4 @@
assertEquals(0, 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/internal/analysis/MethodAnalyzerTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/MethodAnalyzerTest.java
index 6bcbd63..dbe0af6 100644
--- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/MethodAnalyzerTest.java
+++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/MethodAnalyzerTest.java
@@ -580,8 +580,8 @@
private void runMethodAnalzer() {
LabelFlowAnalyzer.markLabels(method);
- final MethodAnalyzer analyzer = new MethodAnalyzer("doit", "()V", null,
- probes);
+ final MethodAnalyzer analyzer = new MethodAnalyzer("Foo",
+ "java/lang/Object", "doit", "()V", null, probes);
final MethodProbesAdapter probesAdapter = new MethodProbesAdapter(
analyzer, this);
// note that CheckMethodAdapter verifies that this test does not violate
diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/EnumFilterTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/EnumFilterTest.java
new file mode 100644
index 0000000..149990f
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/EnumFilterTest.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * 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.internal.analysis.filter;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.jacoco.core.internal.instr.InstrSupport;
+import org.junit.Test;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.MethodNode;
+
+public class EnumFilterTest implements IFilterOutput {
+
+ private final EnumFilter filter = new EnumFilter();
+
+ private AbstractInsnNode fromInclusive;
+ private AbstractInsnNode toInclusive;
+
+ @Test
+ public void testValues() {
+ final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, 0,
+ "values", "()[LFoo;", null, null);
+ m.visitInsn(Opcodes.NOP);
+
+ filter.filter("Foo", "java/lang/Enum", m, this);
+
+ assertEquals(m.instructions.getFirst(), fromInclusive);
+ assertEquals(m.instructions.getLast(), toInclusive);
+ }
+
+ @Test
+ public void testNonValues() {
+ final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, 0,
+ "values", "()V", null, null);
+ m.visitInsn(Opcodes.NOP);
+
+ filter.filter("Foo", "java/lang/Enum", m, this);
+
+ assertNull(fromInclusive);
+ assertNull(toInclusive);
+ }
+
+ @Test
+ public void testValueOf() {
+ final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, 0,
+ "valueOf", "(Ljava/lang/String;)LFoo;", null, null);
+ m.visitInsn(Opcodes.NOP);
+
+ filter.filter("Foo", "java/lang/Enum", m, this);
+
+ assertEquals(m.instructions.getFirst(), fromInclusive);
+ assertEquals(m.instructions.getLast(), toInclusive);
+ }
+
+ @Test
+ public void testNonValueOf() {
+ final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, 0,
+ "valueOf", "()V", null, null);
+ m.visitInsn(Opcodes.NOP);
+
+ filter.filter("Foo", "java/lang/Enum", m, this);
+
+ assertNull(fromInclusive);
+ assertNull(toInclusive);
+ }
+
+ @Test
+ public void testNonEnum() {
+ final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, 0,
+ "values", "()[LFoo;", null, null);
+ m.visitInsn(Opcodes.NOP);
+
+ filter.filter("Foo", "java/lang/Object", m, this);
+
+ assertNull(fromInclusive);
+ assertNull(toInclusive);
+ }
+
+ public void ignore(final AbstractInsnNode fromInclusive,
+ final AbstractInsnNode toInclusive) {
+ assertNull(this.fromInclusive);
+ this.fromInclusive = fromInclusive;
+ this.toInclusive = toInclusive;
+ }
+
+}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/LombokGeneratedFilterTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/LombokGeneratedFilterTest.java
index a1fdcae..58f93fb 100644
--- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/LombokGeneratedFilterTest.java
+++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/LombokGeneratedFilterTest.java
@@ -38,7 +38,7 @@
m.visitInsn(Opcodes.ICONST_0);
m.visitInsn(Opcodes.IRETURN);
- filter.filter(m, this);
+ filter.filter("Foo", "java/lang/Object", m, this);
assertNull(fromInclusive);
assertNull(toInclusive);
@@ -53,7 +53,7 @@
m.visitInsn(Opcodes.ICONST_0);
m.visitInsn(Opcodes.IRETURN);
- filter.filter(m, this);
+ filter.filter("Foo", "java/lang/Object", m, this);
assertNull(fromInclusive);
assertNull(toInclusive);
@@ -68,7 +68,7 @@
m.visitInsn(Opcodes.ICONST_0);
m.visitInsn(Opcodes.IRETURN);
- filter.filter(m, this);
+ filter.filter("Foo", "java/lang/Object", m, this);
assertEquals(m.instructions.getFirst(), fromInclusive);
assertEquals(m.instructions.getLast(), toInclusive);
diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/SynchronizedFilterTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/SynchronizedFilterTest.java
index b315dda..b0f5d1b 100644
--- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/SynchronizedFilterTest.java
+++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/SynchronizedFilterTest.java
@@ -63,7 +63,7 @@
m.visitLabel(exit);
m.visitInsn(Opcodes.RETURN);
- filter.filter(m, this);
+ filter.filter("Foo", "java/lang/Object", m, this);
assertEquals(handler.info, fromInclusive);
assertEquals(((LabelNode) exit.info).getPrevious(), toInclusive);
}
@@ -116,7 +116,7 @@
m.visitLabel(exit);
m.visitInsn(Opcodes.RETURN);
- filter.filter(m, this);
+ filter.filter("Foo", "java/lang/Object", m, this);
assertNull(fromInclusive);
}
@@ -151,7 +151,7 @@
m.visitLabel(exit);
m.visitInsn(Opcodes.RETURN);
- filter.filter(m, this);
+ filter.filter("Foo", "java/lang/Object", m, this);
assertEquals(handler.info, fromInclusive);
assertEquals(((LabelNode) exit.info).getPrevious(), toInclusive);
}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/SyntheticFilterTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/SyntheticFilterTest.java
index 75648dc..319caef 100644
--- a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/SyntheticFilterTest.java
+++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/SyntheticFilterTest.java
@@ -11,15 +11,15 @@
*******************************************************************************/
package org.jacoco.core.internal.analysis.filter;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
import org.jacoco.core.internal.instr.InstrSupport;
import org.junit.Test;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.MethodNode;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-
public class SyntheticFilterTest implements IFilterOutput {
private final SyntheticFilter filter = new SyntheticFilter();
@@ -33,7 +33,7 @@
"name", "()V", null, null);
m.visitInsn(Opcodes.NOP);
- filter.filter(m, this);
+ filter.filter("Foo", "java/lang/Object", m, this);
assertNull(fromInclusive);
assertNull(toInclusive);
@@ -45,7 +45,7 @@
Opcodes.ACC_SYNTHETIC, "name", "()V", null, null);
m.visitInsn(Opcodes.NOP);
- filter.filter(m, this);
+ filter.filter("Foo", "java/lang/Object", m, this);
assertEquals(m.instructions.getFirst(), fromInclusive);
assertEquals(m.instructions.getLast(), toInclusive);
@@ -57,7 +57,7 @@
Opcodes.ACC_SYNTHETIC, "lambda$1", "()V", null, null);
m.visitInsn(Opcodes.NOP);
- filter.filter(m, this);
+ filter.filter("Foo", "java/lang/Object", m, this);
assertNull(fromInclusive);
assertNull(toInclusive);
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
index aaa5e98..69a2ed9 100644
--- 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
@@ -29,7 +29,7 @@
/**
* This method should not be excluded from analysis unlike implicitly
* created {@link #valueOf(String)} method that refers to the line of enum
- * definition.
+ * definition in case of javac and to the first line in case of ECJ.
*/
public void valueOf() {
} // $line-customValueOfMethod$
@@ -37,7 +37,7 @@
/**
* This method should not be excluded from analysis unlike implicitly
* created {@link #values()} method that refers to the line of enum
- * definition.
+ * definition in case of javac and to the first line in case of ECJ.
*/
public void values(Object o) {
} // $line-customValuesMethod$
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 38037be..fa3517b 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
@@ -63,12 +63,8 @@
InstrSupport.assertNotInstrumented(name, coverage.getName());
- if (isMethodFiltered(coverage.getName(), coverage.getSuperName(), name,
- desc)) {
- return null;
- }
-
- return new MethodAnalyzer(stringPool.get(name), stringPool.get(desc),
+ return new MethodAnalyzer(coverage.getName(), coverage.getSuperName(),
+ stringPool.get(name), stringPool.get(desc),
stringPool.get(signature), probes) {
@Override
public void visitEnd() {
@@ -82,27 +78,6 @@
};
}
- /**
- * @return <code>true</code> if method should not be analyzed
- */
- // TODO: Use filter hook in future
- private boolean isMethodFiltered(final String className,
- final String superClassName, 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 false;
- }
-
@Override
public FieldVisitor visitField(final int access, final String name,
final String desc, final String signature, final Object value) {
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/MethodAnalyzer.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/MethodAnalyzer.java
index e5dde70..993fe88 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/MethodAnalyzer.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/MethodAnalyzer.java
@@ -19,6 +19,7 @@
import org.jacoco.core.analysis.ICounter;
import org.jacoco.core.analysis.IMethodCoverage;
import org.jacoco.core.analysis.ISourceNode;
+import org.jacoco.core.internal.analysis.filter.EnumFilter;
import org.jacoco.core.internal.analysis.filter.IFilter;
import org.jacoco.core.internal.analysis.filter.IFilterOutput;
import org.jacoco.core.internal.analysis.filter.LombokGeneratedFilter;
@@ -42,10 +43,14 @@
public class MethodAnalyzer extends MethodProbesVisitor
implements IFilterOutput {
- private static final IFilter[] FILTERS = new IFilter[] {
+ private static final IFilter[] FILTERS = new IFilter[] { new EnumFilter(),
new SyntheticFilter(), new SynchronizedFilter(),
new LombokGeneratedFilter() };
+ private final String className;
+
+ private final String superClassName;
+
private final boolean[] probes;
private final MethodCoverageImpl coverage;
@@ -74,6 +79,10 @@
/**
* New Method analyzer for the given probe data.
*
+ * @param className
+ * class name
+ * @param superClassName
+ * superclass name
* @param name
* method name
* @param desc
@@ -85,9 +94,12 @@
* recorded probe date of the containing class or
* <code>null</code> if the class is not executed at all
*/
- public MethodAnalyzer(final String name, final String desc,
- final String signature, final boolean[] probes) {
+ public MethodAnalyzer(final String className, final String superClassName,
+ final String name, final String desc, final String signature,
+ final boolean[] probes) {
super();
+ this.className = className;
+ this.superClassName = superClassName;
this.probes = probes;
this.coverage = new MethodCoverageImpl(name, desc, signature);
}
@@ -110,7 +122,7 @@
final MethodVisitor methodVisitor) {
this.ignored.clear();
for (final IFilter filter : FILTERS) {
- filter.filter(methodNode, this);
+ filter.filter(className, superClassName, methodNode, this);
}
for (final TryCatchBlockNode n : methodNode.tryCatchBlocks) {
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/EnumFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/EnumFilter.java
new file mode 100644
index 0000000..852008e
--- /dev/null
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/EnumFilter.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.internal.analysis.filter;
+
+import org.objectweb.asm.tree.MethodNode;
+
+/**
+ * Filters methods <code>values</code> and <code>valueOf</code> that compiler
+ * creates for enums.
+ */
+public final class EnumFilter implements IFilter {
+
+ public void filter(final String className, final String superClassName,
+ final MethodNode methodNode, final IFilterOutput output) {
+ if (isMethodFiltered(className, superClassName, methodNode.name,
+ methodNode.desc)) {
+ output.ignore(methodNode.instructions.getFirst(),
+ methodNode.instructions.getLast());
+ }
+ }
+
+ private boolean isMethodFiltered(final String className,
+ final String superClassName, final String methodName,
+ final String methodDesc) {
+ if ("java/lang/Enum".equals(superClassName)) {
+ if ("values".equals(methodName)
+ && ("()[L" + className + ";").equals(methodDesc)) {
+ return true;
+ }
+ if ("valueOf".equals(methodName)
+ && ("(Ljava/lang/String;)L" + className + ";")
+ .equals(methodDesc)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/IFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/IFilter.java
index c1bab8e..39cf5c7 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/IFilter.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/IFilter.java
@@ -23,12 +23,17 @@
* This method is called for every method. The filter implementation is
* expected to inspect the provided method and report its result to the
* given {@link IFilterOutput} instance.
- *
+ *
+ * @param className
+ * class name
+ * @param superClassName
+ * superclass name
* @param methodNode
* method to inspect
* @param output
* callback to report filtering results to
*/
- void filter(MethodNode methodNode, IFilterOutput output);
+ void filter(String className, String superClassName, MethodNode methodNode,
+ IFilterOutput output);
}
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/LombokGeneratedFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/LombokGeneratedFilter.java
index 9f23ecd..571e464 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/LombokGeneratedFilter.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/LombokGeneratedFilter.java
@@ -21,8 +21,8 @@
*/
public class LombokGeneratedFilter implements IFilter {
- public void filter(final MethodNode methodNode,
- final IFilterOutput output) {
+ public void filter(final String className, final String superClassName,
+ final MethodNode methodNode, final IFilterOutput output) {
if (hasLombokGeneratedAnnotation(methodNode)) {
output.ignore(methodNode.instructions.getFirst(),
methodNode.instructions.getLast());
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/SynchronizedFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/SynchronizedFilter.java
index 65e763d..655226e 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/SynchronizedFilter.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/SynchronizedFilter.java
@@ -21,7 +21,8 @@
*/
public final class SynchronizedFilter implements IFilter {
- public void filter(MethodNode methodNode, IFilterOutput output) {
+ public void filter(final String className, final String superClassName,
+ final MethodNode methodNode, final IFilterOutput output) {
for (TryCatchBlockNode tryCatch : methodNode.tryCatchBlocks) {
if (tryCatch.type != null) {
continue;
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/SyntheticFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/SyntheticFilter.java
index 540909d..454ec80 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/SyntheticFilter.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/SyntheticFilter.java
@@ -19,7 +19,8 @@
*/
public final class SyntheticFilter implements IFilter {
- public void filter(MethodNode methodNode, IFilterOutput output) {
+ public void filter(final String className, final String superClassName,
+ final MethodNode methodNode, final IFilterOutput output) {
if ((methodNode.access & Opcodes.ACC_SYNTHETIC) != 0
&& !methodNode.name.startsWith("lambda$")) {
output.ignore(methodNode.instructions.getFirst(),