diff options
4 files changed, 137 insertions, 3 deletions
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 new file mode 100644 index 00000000..a1fdcae9 --- /dev/null +++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/filter/LombokGeneratedFilterTest.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * 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 java.util.Arrays; + +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.AnnotationNode; +import org.objectweb.asm.tree.MethodNode; + +public class LombokGeneratedFilterTest implements IFilterOutput { + + private final IFilter filter = new LombokGeneratedFilter(); + + 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(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;", false); + + m.visitInsn(Opcodes.ICONST_0); + m.visitInsn(Opcodes.IRETURN); + + filter.filter(m, this); + + assertNull(fromInclusive); + assertNull(toInclusive); + } + + @Test + public void testLombokGeneratedAnnotation() { + final MethodNode m = new MethodNode(InstrSupport.ASM_API_VERSION, 0, + "hashCode", "()I", null, null); + m.visitAnnotation("Llombok/Generated;", false); + + m.visitInsn(Opcodes.ICONST_0); + m.visitInsn(Opcodes.IRETURN); + + filter.filter(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; + } + +} 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 a912e333..e5dde709 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 @@ -21,6 +21,7 @@ import org.jacoco.core.analysis.IMethodCoverage; import org.jacoco.core.analysis.ISourceNode; import org.jacoco.core.internal.analysis.filter.IFilter; import org.jacoco.core.internal.analysis.filter.IFilterOutput; +import org.jacoco.core.internal.analysis.filter.LombokGeneratedFilter; import org.jacoco.core.internal.analysis.filter.SynchronizedFilter; import org.jacoco.core.internal.analysis.filter.SyntheticFilter; import org.jacoco.core.internal.flow.IFrame; @@ -42,7 +43,8 @@ public class MethodAnalyzer extends MethodProbesVisitor implements IFilterOutput { private static final IFilter[] FILTERS = new IFilter[] { - new SyntheticFilter(), new SynchronizedFilter() }; + new SyntheticFilter(), new SynchronizedFilter(), + new LombokGeneratedFilter() }; private final boolean[] probes; @@ -328,8 +330,9 @@ public class MethodAnalyzer extends MethodProbesVisitor final int covered = i.getCoveredBranches(); final ICounter instrCounter = covered == 0 ? CounterImpl.COUNTER_1_0 : CounterImpl.COUNTER_0_1; - final ICounter branchCounter = total > 1 ? CounterImpl.getInstance( - total - covered, covered) : CounterImpl.COUNTER_0_0; + final ICounter branchCounter = total > 1 + ? CounterImpl.getInstance(total - covered, covered) + : CounterImpl.COUNTER_0_0; coverage.increment(instrCounter, branchCounter, i.getLine()); } coverage.incrementMethodCounter(); 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 new file mode 100644 index 00000000..9f23ecd8 --- /dev/null +++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/LombokGeneratedFilter.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * 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>@lombok.Generated</code>. + */ +public class LombokGeneratedFilter implements IFilter { + + public void filter(final MethodNode methodNode, + final IFilterOutput output) { + if (hasLombokGeneratedAnnotation(methodNode)) { + output.ignore(methodNode.instructions.getFirst(), + methodNode.instructions.getLast()); + } + } + + 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; + } + +} diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html index c73b155d..43e42aa4 100644 --- a/org.jacoco.doc/docroot/doc/changes.html +++ b/org.jacoco.doc/docroot/doc/changes.html @@ -28,6 +28,9 @@ <li>Exclude from a report a part of bytecode that compiler generates for a synchronized statement (GitHub <a href="https://github.com/jacoco/jacoco/issues/501">#501</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. + (GitHub <a href="https://github.com/jacoco/jacoco/issues/513">#513</a>).</li> <li>Maven aggregated reports will now also include modules of runtime dependencies (GitHub <a href="https://github.com/jacoco/jacoco/issues/498">#498</a>).</li> </ul> |