aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Hoffmann <datoma@users.noreply.github.com>2017-10-17 22:58:04 +0200
committerEvgeny Mandrikov <Godin@users.noreply.github.com>2017-10-17 22:58:04 +0200
commitec6287a6b947b8e91a1c697aebdb157bbfab564b (patch)
tree0305fc76f722632950eba1fc334eb2222d11e798
parent88d7b01d00451a1351aa7eec4783860844b58c29 (diff)
downloadjacoco-ec6287a6b947b8e91a1c697aebdb157bbfab564b.tar.gz
Add filter for methods annotated with @groovy.transform.Generated (#610)
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/GroovyGeneratedFilterTest.java86
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/AbstractAnnotatedMethodFilter.java66
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/Filters.java5
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/GroovyGeneratedFilter.java36
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/LombokGeneratedFilter.java26
-rw-r--r--org.jacoco.doc/docroot/doc/changes.html6
6 files changed, 205 insertions, 20 deletions
diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/GroovyGeneratedFilterTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/GroovyGeneratedFilterTest.java
new file mode 100644
index 00000000..4630762a
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/GroovyGeneratedFilterTest.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * 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:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ *******************************************************************************/
+package org.jacoco.core.internal.analysis.filter;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+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 GroovyGeneratedFilterTest implements IFilterOutput {
+
+ private final IFilter filter = new GroovyGeneratedFilter();
+
+ private AbstractInsnNode fromInclusive;
+ private AbstractInsnNode toInclusive;
+
+ @Test
+ public void testNoAnnotations() {
+ final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, 0,
+ "hashCode", "()I", null, null);
+
+ m.visitInsn(Opcodes.ICONST_0);
+ m.visitInsn(Opcodes.IRETURN);
+
+ filter.filter("Foo", "java/lang/Object", m, this);
+
+ assertNull(fromInclusive);
+ assertNull(toInclusive);
+ }
+
+ @Test
+ public void testOtherAnnotation() {
+ final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, 0,
+ "hashCode", "()I", null, null);
+ m.visitAnnotation("Lother/Annotation;", true);
+
+ m.visitInsn(Opcodes.ICONST_0);
+ m.visitInsn(Opcodes.IRETURN);
+
+ filter.filter("Foo", "java/lang/Object", m, this);
+
+ assertNull(fromInclusive);
+ assertNull(toInclusive);
+ }
+
+ @Test
+ public void testGroovyGeneratedAnnotation() {
+ final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, 0,
+ "hashCode", "()I", null, null);
+ m.visitAnnotation("Lgroovy/transform/Generated;", true);
+
+ m.visitInsn(Opcodes.ICONST_0);
+ m.visitInsn(Opcodes.IRETURN);
+
+ filter.filter("Foo", "java/lang/Object", m, this);
+
+ assertEquals(m.instructions.getFirst(), fromInclusive);
+ assertEquals(m.instructions.getLast(), toInclusive);
+ }
+
+ public void ignore(final AbstractInsnNode fromInclusive,
+ final AbstractInsnNode toInclusive) {
+ assertNull(this.fromInclusive);
+ this.fromInclusive = fromInclusive;
+ this.toInclusive = toInclusive;
+ }
+
+ public void merge(final AbstractInsnNode i1, final AbstractInsnNode i2) {
+ fail();
+ }
+
+}
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/AbstractAnnotatedMethodFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/AbstractAnnotatedMethodFilter.java
new file mode 100644
index 00000000..75e33093
--- /dev/null
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/AbstractAnnotatedMethodFilter.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * 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:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ *******************************************************************************/
+package org.jacoco.core.internal.analysis.filter;
+
+import java.util.List;
+
+import org.objectweb.asm.tree.AnnotationNode;
+import org.objectweb.asm.tree.MethodNode;
+
+/**
+ * Filters annotated methods.
+ */
+abstract class AbstractAnnotatedMethodFilter implements IFilter {
+ private final String descType;
+
+ /**
+ * Configures a new filter instance.
+ *
+ * @param annotationType
+ * VM type of the annotation
+ */
+ protected AbstractAnnotatedMethodFilter(final String annotationType) {
+ this.descType = "L" + annotationType + ";";
+ }
+
+ public void filter(final String className, final String superClassName,
+ final MethodNode methodNode, final IFilterOutput output) {
+ if (hasAnnotation(methodNode)) {
+ output.ignore(methodNode.instructions.getFirst(),
+ methodNode.instructions.getLast());
+ }
+ }
+
+ private boolean hasAnnotation(final MethodNode methodNode) {
+ final List<AnnotationNode> annotations = getAnnotations(methodNode);
+ if (annotations != null) {
+ for (final AnnotationNode annotation : annotations) {
+ if (descType.equals(annotation.desc)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Retrieves the annotations to search from a method. Depending on the
+ * retention of the annotation this is either
+ * <code>visibleAnnotations</code> or <code>invisibleAnnotations</code>.
+ *
+ * @param methodNode
+ * method to retrieve annotations from
+ * @return list of annotations
+ */
+ abstract List<AnnotationNode> getAnnotations(final MethodNode methodNode);
+
+}
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/Filters.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/Filters.java
index e2c26d92..4b2a64a9 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/Filters.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/Filters.java
@@ -30,11 +30,12 @@ public final class Filters implements IFilter {
new SyntheticFilter(), new SynchronizedFilter(),
new TryWithResourcesJavacFilter(), new TryWithResourcesEcjFilter(),
new PrivateEmptyNoArgConstructorFilter(),
- new StringSwitchJavacFilter(), new LombokGeneratedFilter());
+ new StringSwitchJavacFilter(), new LombokGeneratedFilter(),
+ new GroovyGeneratedFilter());
private final IFilter[] filters;
- private Filters(IFilter... filters) {
+ private Filters(final IFilter... filters) {
this.filters = filters;
}
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/GroovyGeneratedFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/GroovyGeneratedFilter.java
new file mode 100644
index 00000000..353868d5
--- /dev/null
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/GroovyGeneratedFilter.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * 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:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ *******************************************************************************/
+package org.jacoco.core.internal.analysis.filter;
+
+import java.util.List;
+
+import org.objectweb.asm.tree.AnnotationNode;
+import org.objectweb.asm.tree.MethodNode;
+
+/**
+ * Filters methods annotated with <code>@groovy.transform.Generated</code>.
+ */
+public final class GroovyGeneratedFilter extends AbstractAnnotatedMethodFilter {
+
+ /**
+ * New filter.
+ */
+ public GroovyGeneratedFilter() {
+ super("groovy/transform/Generated");
+ }
+
+ @Override
+ List<AnnotationNode> getAnnotations(final MethodNode methodNode) {
+ return methodNode.visibleAnnotations;
+ }
+
+}
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 98575e80..62021ae7 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
@@ -19,26 +19,18 @@ import org.objectweb.asm.tree.MethodNode;
/**
* Filters methods annotated with <code>@lombok.Generated</code>.
*/
-public final class LombokGeneratedFilter implements IFilter {
+public final class LombokGeneratedFilter extends AbstractAnnotatedMethodFilter {
- 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());
- }
+ /**
+ * New filter.
+ */
+ public LombokGeneratedFilter() {
+ super("lombok/Generated");
}
- private boolean hasLombokGeneratedAnnotation(final MethodNode methodNode) {
- final List<AnnotationNode> runtimeInvisibleAnnotations = methodNode.invisibleAnnotations;
- if (runtimeInvisibleAnnotations != null) {
- for (final AnnotationNode annotation : runtimeInvisibleAnnotations) {
- if ("Llombok/Generated;".equals(annotation.desc)) {
- return true;
- }
- }
- }
- return false;
+ @Override
+ List<AnnotationNode> getAnnotations(final MethodNode methodNode) {
+ return methodNode.invisibleAnnotations;
}
}
diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html
index 5ae14dd5..b9e61a12 100644
--- a/org.jacoco.doc/docroot/doc/changes.html
+++ b/org.jacoco.doc/docroot/doc/changes.html
@@ -35,8 +35,12 @@
try-with-resources statement
(GitHub <a href="https://github.com/jacoco/jacoco/issues/500">#500</a>).</li>
<li>Exclude from a report methods which are annotated with <code>@lombok.Generated</code>.
- Initial analysis and contribution by RĂ¼diger zu Dohna.
+ Initial analysis and contribution by RĂ¼diger zu Dohna
(GitHub <a href="https://github.com/jacoco/jacoco/issues/513">#513</a>).</li>
+ <li>Exclude from a report methods which are annotated with
+ <code>@groovy.transform.Generated</code> to better integrate with Groovy
+ >= 2.5.0. Thanks to Andres Almiray for adding the annotation to Groovy
+ (GitHub <a href="https://github.com/jacoco/jacoco/issues/610">#610</a>).</li>
<li>Exclude from a report private empty constructors that do not have arguments
(GitHub <a href="https://github.com/jacoco/jacoco/issues/529">#529</a>).</li>
<li>Exclude from a report a part of bytecode that javac generates for a