aboutsummaryrefslogtreecommitdiff
path: root/org.jacoco.core.test.validation.java5
diff options
context:
space:
mode:
Diffstat (limited to 'org.jacoco.core.test.validation.java5')
-rw-r--r--org.jacoco.core.test.validation.java5/.classpath20
-rw-r--r--org.jacoco.core.test.validation.java5/.project30
-rw-r--r--org.jacoco.core.test.validation.java5/pom.xml33
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/AnnotationGeneratedTest.java23
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/AnnotationInitializerTest.java40
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/BadCycleClassTest.java35
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/BooleanExpressionsTest.java26
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/ClassInitializerTest.java26
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/ConstructorsTest.java27
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/ControlStructureBeforeSuperConstructorTest.java27
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/ControlStructuresTest.java26
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/CyclomaticComplexityTest.java280
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/EnumConstructorTest.java26
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/EnumImplicitMethodsTest.java32
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/EnumSwitchTest.java38
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/ExceptionsTest.java83
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/ExplicitInitialFrameTest.java26
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/FieldInitializationInTwoConstructorsTest.java27
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/FinallyTest.java230
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/FramesTest.java170
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/ImplicitFieldInitializationTest.java26
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/InterfaceClassInitializerTest.java32
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/StructuredLockingTest.java196
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/SynchronizedTest.java54
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/SyntheticTest.java30
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/AnnotationGeneratedTarget.java92
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/AnnotationInitializerTarget.java23
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/BadCycleClassTarget.java46
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/BooleanExpressionsTarget.java120
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/ClassInitializerTarget.java53
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/ConstructorsTarget.java95
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/ControlStructureBeforeSuperConstructorTarget.java33
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/ControlStructuresTarget.java293
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/EnumConstructorTarget.java55
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/EnumImplicitMethodsTarget.java50
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/EnumSwitchTarget.java42
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/ExceptionsTarget.java154
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/ExplicitInitialFrameTarget.java31
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/FieldInitializationInTwoConstructorsTarget.java34
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/FinallyTarget.java161
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/ImplicitFieldInitializationTarget.java31
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/InterfaceClassInitializerTarget.java33
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/StructuredLockingTarget.java46
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/SynchronizedTarget.java61
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/SyntheticTarget.java64
45 files changed, 3080 insertions, 0 deletions
diff --git a/org.jacoco.core.test.validation.java5/.classpath b/org.jacoco.core.test.validation.java5/.classpath
new file mode 100644
index 00000000..ebe550b7
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/.classpath
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5">
+ <attributes>
+ <attribute name="maven.pomderived" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+ <attributes>
+ <attribute name="maven.pomderived" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="src" output="target/classes" path="src">
+ <attributes>
+ <attribute name="optional" value="true"/>
+ <attribute name="maven.pomderived" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/org.jacoco.core.test.validation.java5/.project b/org.jacoco.core.test.validation.java5/.project
new file mode 100644
index 00000000..cfbae43e
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/.project
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.jacoco.core.test.validation.java5</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.m2e.core.maven2Builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.m2e.core.maven2Nature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+ <linkedResources>
+ <link>
+ <name>.settings</name>
+ <type>2</type>
+ <locationURI>PARENT-1-PROJECT_LOC/org.jacoco.core.test/.settings</locationURI>
+ </link>
+ </linkedResources>
+</projectDescription>
diff --git a/org.jacoco.core.test.validation.java5/pom.xml b/org.jacoco.core.test.validation.java5/pom.xml
new file mode 100644
index 00000000..4591189a
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/pom.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2009, 2019 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
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.jacoco</groupId>
+ <artifactId>org.jacoco.core.test.validation</artifactId>
+ <version>0.8.4</version>
+ <relativePath>../org.jacoco.core.test.validation</relativePath>
+ </parent>
+
+ <artifactId>org.jacoco.core.test.validation.java5</artifactId>
+
+ <name>JaCoCo :: Test :: Core :: Validation Java 5</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>org.jacoco.core.test</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/AnnotationGeneratedTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/AnnotationGeneratedTest.java
new file mode 100644
index 00000000..c56e6125
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/AnnotationGeneratedTest.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.java5;
+
+import org.jacoco.core.test.validation.ValidationTestBase;
+import org.jacoco.core.test.validation.java5.targets.AnnotationGeneratedTarget;
+
+public class AnnotationGeneratedTest extends ValidationTestBase {
+
+ public AnnotationGeneratedTest() {
+ super(AnnotationGeneratedTarget.class);
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/AnnotationInitializerTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/AnnotationInitializerTest.java
new file mode 100644
index 00000000..01a721f5
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/AnnotationInitializerTest.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.java5;
+
+import static org.junit.Assert.assertEquals;
+
+import org.jacoco.core.test.validation.ValidationTestBase;
+import org.jacoco.core.test.validation.java5.targets.AnnotationInitializerTarget;
+
+/**
+ * Test of initializer in annotations.
+ */
+public class AnnotationInitializerTest extends ValidationTestBase {
+
+ public AnnotationInitializerTest() {
+ super(AnnotationInitializerTarget.class);
+ }
+
+ @Override
+ protected void run(Class<?> targetClass) throws Exception {
+ // Instrumentation should not add members,
+ // otherwise sun.reflect.annotation.AnnotationInvocationHandler
+ // can throw java.lang.annotation.AnnotationFormatError
+ assertEquals(1, targetClass.getDeclaredFields().length);
+ assertEquals(1, targetClass.getDeclaredMethods().length);
+
+ // Force initialization
+ targetClass.getField("CONST").get(null);
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/BadCycleClassTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/BadCycleClassTest.java
new file mode 100644
index 00000000..cb6758bd
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/BadCycleClassTest.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.java5;
+
+import org.jacoco.core.test.validation.ValidationTestBase;
+import org.jacoco.core.test.validation.java5.targets.BadCycleClassTarget;
+import org.junit.Test;
+
+/**
+ * Test of "bad cycles" with classes.
+ */
+public class BadCycleClassTest extends ValidationTestBase {
+
+ public BadCycleClassTest() throws Exception {
+ super(BadCycleClassTarget.class);
+ }
+
+ @Test
+ public void method_execution_sequence() throws Exception {
+ // The cycle causes a constructor and instance method to be called
+ // before the static initializer of a class:
+ assertLogEvents("childinit", "childsomeMethod", "childclinit",
+ "childinit");
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/BooleanExpressionsTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/BooleanExpressionsTest.java
new file mode 100644
index 00000000..366730e4
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/BooleanExpressionsTest.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.test.validation.java5;
+
+import org.jacoco.core.test.validation.ValidationTestBase;
+import org.jacoco.core.test.validation.java5.targets.BooleanExpressionsTarget;
+
+/**
+ * Tests of basic Java boolean expressions.
+ */
+public class BooleanExpressionsTest extends ValidationTestBase {
+
+ public BooleanExpressionsTest() {
+ super(BooleanExpressionsTarget.class);
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/ClassInitializerTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/ClassInitializerTest.java
new file mode 100644
index 00000000..cefd5bb2
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/ClassInitializerTest.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.test.validation.java5;
+
+import org.jacoco.core.test.validation.ValidationTestBase;
+import org.jacoco.core.test.validation.java5.targets.ClassInitializerTarget;
+
+/**
+ * Tests of static initializer in classes.
+ */
+public class ClassInitializerTest extends ValidationTestBase {
+
+ public ClassInitializerTest() {
+ super(ClassInitializerTarget.class);
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/ConstructorsTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/ConstructorsTest.java
new file mode 100644
index 00000000..674b3df6
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/ConstructorsTest.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.java5;
+
+import org.jacoco.core.test.validation.ValidationTestBase;
+import org.jacoco.core.test.validation.java5.targets.ConstructorsTarget;
+
+/**
+ * Tests for different constructors. Private empty constructors without
+ * arguments are filtered.
+ */
+public class ConstructorsTest extends ValidationTestBase {
+
+ public ConstructorsTest() {
+ super(ConstructorsTarget.class);
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/ControlStructureBeforeSuperConstructorTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/ControlStructureBeforeSuperConstructorTest.java
new file mode 100644
index 00000000..5381ae2f
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/ControlStructureBeforeSuperConstructorTest.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.test.validation.java5;
+
+import org.jacoco.core.test.validation.ValidationTestBase;
+import org.jacoco.core.test.validation.java5.targets.ControlStructureBeforeSuperConstructorTarget;
+
+/**
+ * Test of probes before the super constructor call.
+ */
+public class ControlStructureBeforeSuperConstructorTest
+ extends ValidationTestBase {
+
+ public ControlStructureBeforeSuperConstructorTest() {
+ super(ControlStructureBeforeSuperConstructorTarget.class);
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/ControlStructuresTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/ControlStructuresTest.java
new file mode 100644
index 00000000..350bbe03
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/ControlStructuresTest.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.test.validation.java5;
+
+import org.jacoco.core.test.validation.ValidationTestBase;
+import org.jacoco.core.test.validation.java5.targets.ControlStructuresTarget;
+
+/**
+ * Tests of basic Java control structures.
+ */
+public class ControlStructuresTest extends ValidationTestBase {
+
+ public ControlStructuresTest() {
+ super(ControlStructuresTarget.class);
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/CyclomaticComplexityTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/CyclomaticComplexityTest.java
new file mode 100644
index 00000000..6bc16140
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/CyclomaticComplexityTest.java
@@ -0,0 +1,280 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.test.validation.java5;
+
+import static org.jacoco.core.test.validation.targets.Stubs.nop;
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.util.Collection;
+
+import org.jacoco.core.analysis.Analyzer;
+import org.jacoco.core.analysis.CoverageBuilder;
+import org.jacoco.core.analysis.IClassCoverage;
+import org.jacoco.core.analysis.ICounter;
+import org.jacoco.core.analysis.IMethodCoverage;
+import org.jacoco.core.data.ExecutionDataStore;
+import org.jacoco.core.data.SessionInfoStore;
+import org.jacoco.core.instr.Instrumenter;
+import org.jacoco.core.internal.analysis.CounterImpl;
+import org.jacoco.core.runtime.IRuntime;
+import org.jacoco.core.runtime.RuntimeData;
+import org.jacoco.core.runtime.SystemPropertiesRuntime;
+import org.jacoco.core.test.TargetLoader;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Various tests for cyclomatic complexity of methods.
+ */
+public class CyclomaticComplexityTest {
+
+ public interface Target {
+ public void test(int arg);
+ }
+
+ private RuntimeData data;
+ private IRuntime runtime;
+ private byte[] bytes;
+ private Target target;
+
+ @Before
+ public void setup() throws Exception {
+ data = new RuntimeData();
+ runtime = new SystemPropertiesRuntime();
+ runtime.startup(data);
+ }
+
+ @After
+ public void teardown() {
+ runtime.shutdown();
+ }
+
+ public static class Simple implements Target {
+ public void test(int arg) {
+ nop();
+ nop();
+ nop();
+ }
+ }
+
+ @Test
+ public void testSimple1() throws Exception {
+ instrument(Simple.class);
+ final ICounter complexity = analyze();
+ assertEquals(CounterImpl.getInstance(1, 0), complexity);
+ }
+
+ @Test
+ public void testSimple2() throws Exception {
+ instrument(Simple.class);
+ target.test(0);
+ final ICounter complexity = analyze();
+ assertEquals(CounterImpl.getInstance(0, 1), complexity);
+ }
+
+ public static class If implements Target {
+ public void test(int arg) {
+ if (arg == 0) {
+ nop();
+ }
+ }
+ }
+
+ @Test
+ public void testIf1() throws Exception {
+ instrument(If.class);
+ final ICounter complexity = analyze();
+ assertEquals(CounterImpl.getInstance(2, 0), complexity);
+ }
+
+ @Test
+ public void testIf2() throws Exception {
+ instrument(If.class);
+ target.test(0);
+ final ICounter complexity = analyze();
+ assertEquals(CounterImpl.getInstance(1, 1), complexity);
+ }
+
+ @Test
+ public void testIf3() throws Exception {
+ instrument(If.class);
+ target.test(0);
+ target.test(1);
+ final ICounter complexity = analyze();
+ assertEquals(CounterImpl.getInstance(0, 2), complexity);
+ }
+
+ public static class TwoIf implements Target {
+ public void test(int arg) {
+ if (arg < 0) {
+ nop();
+ }
+ if (arg > 0) {
+ nop();
+ }
+ }
+ }
+
+ @Test
+ public void testTwoIf1() throws Exception {
+ instrument(TwoIf.class);
+ final ICounter complexity = analyze();
+ assertEquals(CounterImpl.getInstance(3, 0), complexity);
+ }
+
+ @Test
+ public void testTwoIf2() throws Exception {
+ instrument(TwoIf.class);
+ target.test(-1);
+ final ICounter complexity = analyze();
+ assertEquals(CounterImpl.getInstance(2, 1), complexity);
+ }
+
+ @Test
+ public void testTwoIf3() throws Exception {
+ instrument(TwoIf.class);
+ target.test(-1);
+ target.test(0);
+ final ICounter complexity = analyze();
+ assertEquals(CounterImpl.getInstance(1, 2), complexity);
+ }
+
+ @Test
+ public void testTwoIf4() throws Exception {
+ instrument(TwoIf.class);
+ target.test(-1);
+ target.test(+1);
+ final ICounter complexity = analyze();
+ assertEquals(CounterImpl.getInstance(0, 3), complexity);
+ }
+
+ public static class NestedIf implements Target {
+ public void test(int arg) {
+ if (arg >= 0) {
+ if (arg == 0) {
+ nop();
+ }
+ nop();
+ }
+ }
+ }
+
+ @Test
+ public void testNestedIf1() throws Exception {
+ instrument(NestedIf.class);
+ final ICounter complexity = analyze();
+ assertEquals(CounterImpl.getInstance(3, 0), complexity);
+ }
+
+ @Test
+ public void testNestedIf2() throws Exception {
+ instrument(NestedIf.class);
+ target.test(-1);
+ final ICounter complexity = analyze();
+ assertEquals(CounterImpl.getInstance(2, 1), complexity);
+ }
+
+ @Test
+ public void testNestedIf3() throws Exception {
+ instrument(NestedIf.class);
+ target.test(-1);
+ target.test(0);
+ final ICounter complexity = analyze();
+ assertEquals(CounterImpl.getInstance(1, 2), complexity);
+ }
+
+ @Test
+ public void testNestedIf4() throws Exception {
+ instrument(NestedIf.class);
+ target.test(-1);
+ target.test(0);
+ target.test(+1);
+ final ICounter complexity = analyze();
+ assertEquals(CounterImpl.getInstance(0, 3), complexity);
+ }
+
+ public static class Switch implements Target {
+ public void test(int arg) {
+ switch (arg) {
+ case 1:
+ nop();
+ break;
+ case 2:
+ nop();
+ break;
+ }
+ }
+ }
+
+ @Test
+ public void testSwitch1() throws Exception {
+ instrument(Switch.class);
+ final ICounter complexity = analyze();
+ assertEquals(CounterImpl.getInstance(3, 0), complexity);
+ }
+
+ @Test
+ public void testSwitch2() throws Exception {
+ instrument(Switch.class);
+ target.test(0);
+ final ICounter complexity = analyze();
+ assertEquals(CounterImpl.getInstance(2, 1), complexity);
+ }
+
+ @Test
+ public void testSwitch3() throws Exception {
+ instrument(Switch.class);
+ target.test(0);
+ target.test(1);
+ final ICounter complexity = analyze();
+ assertEquals(CounterImpl.getInstance(1, 2), complexity);
+ }
+
+ @Test
+ public void testSwitch4() throws Exception {
+ instrument(Switch.class);
+ target.test(0);
+ target.test(1);
+ target.test(2);
+ final ICounter complexity = analyze();
+ assertEquals(CounterImpl.getInstance(0, 3), complexity);
+ }
+
+ private void instrument(final Class<? extends Target> clazz)
+ throws Exception {
+ bytes = TargetLoader.getClassDataAsBytes(clazz);
+ final byte[] instrumented = new Instrumenter(runtime).instrument(bytes,
+ "TestTarget");
+ final TargetLoader loader = new TargetLoader();
+ target = (Target) loader.add(clazz, instrumented).newInstance();
+ }
+
+ private ICounter analyze() throws IOException {
+ final CoverageBuilder builder = new CoverageBuilder();
+ final ExecutionDataStore store = new ExecutionDataStore();
+ data.collect(store, new SessionInfoStore(), false);
+ final Analyzer analyzer = new Analyzer(store, builder);
+ analyzer.analyzeClass(bytes, "TestTarget");
+ final Collection<IClassCoverage> classes = builder.getClasses();
+ assertEquals(1, classes.size(), 0.0);
+ final IClassCoverage classCoverage = classes.iterator().next();
+ for (final IMethodCoverage m : classCoverage.getMethods()) {
+ if (m.getName().equals("test")) {
+ return m.getComplexityCounter();
+ }
+ }
+ throw new AssertionError("No test() method.");
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/EnumConstructorTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/EnumConstructorTest.java
new file mode 100644
index 00000000..f11a8b46
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/EnumConstructorTest.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.java5;
+
+import org.jacoco.core.test.validation.ValidationTestBase;
+import org.jacoco.core.test.validation.java5.targets.EnumConstructorTarget;
+
+/**
+ * Test of filtering of enum constructors.
+ */
+public class EnumConstructorTest extends ValidationTestBase {
+
+ public EnumConstructorTest() {
+ super(EnumConstructorTarget.class);
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/EnumImplicitMethodsTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/EnumImplicitMethodsTest.java
new file mode 100644
index 00000000..2653606c
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/EnumImplicitMethodsTest.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.java5;
+
+import org.jacoco.core.test.validation.ValidationTestBase;
+import org.jacoco.core.test.validation.java5.targets.EnumImplicitMethodsTarget;
+import org.junit.Test;
+
+/**
+ * Test of an implicit methods and static initializer in enums.
+ */
+public class EnumImplicitMethodsTest extends ValidationTestBase {
+
+ public EnumImplicitMethodsTest() {
+ super(EnumImplicitMethodsTarget.class);
+ }
+
+ @Test
+ public void test_method_count() {
+ assertMethodCount(5);
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/EnumSwitchTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/EnumSwitchTest.java
new file mode 100644
index 00000000..920c39a7
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/EnumSwitchTest.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.java5;
+
+import org.jacoco.core.test.validation.Source.Line;
+import org.jacoco.core.test.validation.ValidationTestBase;
+import org.jacoco.core.test.validation.java5.targets.EnumSwitchTarget;
+
+/**
+ * Test of filtering of a synthetic class that is generated by javac for a enum
+ * in switch statement.
+ */
+public class EnumSwitchTest extends ValidationTestBase {
+
+ public EnumSwitchTest() {
+ super(EnumSwitchTarget.class);
+ }
+
+ public void assertSwitch(final Line line) {
+ if (isJDKCompiler && JAVA_VERSION.isBefore("1.6")) {
+ // class that holds "switch map" is not marked as synthetic when
+ // compiling with javac 1.5
+ assertPartlyCovered(line, 0, 2);
+ } else {
+ assertFullyCovered(line, 0, 2);
+ }
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/ExceptionsTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/ExceptionsTest.java
new file mode 100644
index 00000000..5e0b78c0
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/ExceptionsTest.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.test.validation.java5;
+
+import org.jacoco.core.test.validation.Source.Line;
+import org.jacoco.core.test.validation.ValidationTestBase;
+import org.jacoco.core.test.validation.java5.targets.ExceptionsTarget;
+
+/**
+ * Tests of exception based control flow.
+ */
+public class ExceptionsTest extends ValidationTestBase {
+
+ public ExceptionsTest() {
+ super(ExceptionsTarget.class);
+ }
+
+ public void assertCatchNoException(final Line line) {
+ if (isJDKCompiler) {
+ assertNotCovered(line);
+ } else {
+ assertPartlyCovered(line);
+ }
+ }
+
+ public void assertCatchBlockEndNoException(final Line line) {
+ if (isJDKCompiler) {
+ assertFullyCovered(line);
+ } else {
+ assertEmpty(line);
+ }
+ }
+
+ public void assertCatchImplicitException(final Line line) {
+ if (isJDKCompiler) {
+ assertFullyCovered(line);
+ } else {
+ assertPartlyCovered(line);
+ }
+ }
+
+ public void assertCatchBlockEndImplicitException(final Line line) {
+ if (isJDKCompiler) {
+ assertNotCovered(line);
+ } else {
+ assertEmpty(line);
+ }
+ }
+
+ public void assertFinally(final Line line) {
+ if (isJDKCompiler) {
+ assertEmpty(line);
+ } else {
+ assertFullyCovered(line);
+ }
+ }
+
+ public void assertFinallyImplicitException(final Line line) {
+ if (isJDKCompiler) {
+ assertEmpty(line);
+ } else {
+ assertNotCovered(line);
+ }
+ }
+
+ public void assertBlockEndImplicitException(final Line line) {
+ if (isJDKCompiler) {
+ assertEmpty(line);
+ } else {
+ assertFullyCovered(line);
+ }
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/ExplicitInitialFrameTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/ExplicitInitialFrameTest.java
new file mode 100644
index 00000000..8b645412
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/ExplicitInitialFrameTest.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.test.validation.java5;
+
+import org.jacoco.core.test.validation.ValidationTestBase;
+import org.jacoco.core.test.validation.java5.targets.ExplicitInitialFrameTarget;
+
+/**
+ * Test for a methods having a explicit initial frame.
+ */
+public class ExplicitInitialFrameTest extends ValidationTestBase {
+
+ public ExplicitInitialFrameTest() {
+ super(ExplicitInitialFrameTarget.class);
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/FieldInitializationInTwoConstructorsTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/FieldInitializationInTwoConstructorsTest.java
new file mode 100644
index 00000000..069e35b2
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/FieldInitializationInTwoConstructorsTest.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.test.validation.java5;
+
+import org.jacoco.core.test.validation.ValidationTestBase;
+import org.jacoco.core.test.validation.java5.targets.FieldInitializationInTwoConstructorsTarget;
+
+/**
+ * Test of field initialization in two constructors.
+ */
+public class FieldInitializationInTwoConstructorsTest
+ extends ValidationTestBase {
+
+ public FieldInitializationInTwoConstructorsTest() {
+ super(FieldInitializationInTwoConstructorsTarget.class);
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/FinallyTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/FinallyTest.java
new file mode 100644
index 00000000..91a81247
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/FinallyTest.java
@@ -0,0 +1,230 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.java5;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.jacoco.core.internal.instr.InstrSupport;
+import org.jacoco.core.test.TargetLoader;
+import org.jacoco.core.test.validation.Source.Line;
+import org.jacoco.core.test.validation.ValidationTestBase;
+import org.jacoco.core.test.validation.java5.targets.FinallyTarget;
+import org.junit.Before;
+import org.junit.Test;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.ClassNode;
+import org.objectweb.asm.tree.LineNumberNode;
+import org.objectweb.asm.tree.MethodNode;
+
+/**
+ * Test of filtering of duplicated bytecode that is generated for finally block.
+ */
+public class FinallyTest extends ValidationTestBase {
+
+ private Map<Integer, String> tags;
+
+ public FinallyTest() {
+ super(FinallyTarget.class);
+ }
+
+ @Before
+ @Override
+ public void setup() throws Exception {
+ super.setup();
+ tags = new HashMap<Integer, String>();
+ }
+
+ public void assertFinally(final Line line) {
+ if (isJDKCompiler) {
+ assertEmpty(line);
+ } else {
+ assertFullyCovered(line);
+ }
+ }
+
+ public void assertTwoRegions1(final Line line) {
+ if (isJDKCompiler && JAVA_VERSION.isBefore("1.8")) {
+ // https://bugs.openjdk.java.net/browse/JDK-7008643
+ assertPartlyCovered(line);
+ } else {
+ assertFullyCovered(line);
+ }
+ }
+
+ public void assertTwoRegionsReturn1(final Line line) {
+ if (isJDKCompiler && JAVA_VERSION.isBefore("1.8")) {
+ // https://bugs.openjdk.java.net/browse/JDK-7008643
+ assertEmpty(line);
+ } else {
+ assertFullyCovered(line);
+ }
+ }
+
+ public void assertTwoRegionsReturn2(final Line line) {
+ if (isJDKCompiler && JAVA_VERSION.isBefore("1.8")) {
+ // https://bugs.openjdk.java.net/browse/JDK-7008643
+ assertEmpty(line);
+ } else {
+ assertNotCovered(line);
+ }
+ }
+
+ public void assertEmptyTry1(final Line line) {
+ if (isJDKCompiler && JAVA_VERSION.isBefore("1.8")) {
+ // compiler bug fixed in javac >= 1.8:
+ assertPartlyCovered(line);
+ } else {
+ assertFullyCovered(line);
+ }
+ }
+
+ public void assertEmptyTry2(final Line line) {
+ if (isJDKCompiler && JAVA_VERSION.isBefore("1.8")) {
+ // compiler bug fixed in javac >= 1.8:
+ assertFullyCovered(line);
+ } else {
+ assertEmpty(line);
+ }
+ }
+
+ public void assertAlwaysCompletesAbruptly0(final Line line) {
+ if (isJDKCompiler) {
+ // uncovered case:
+ assertEmpty(line);
+ } else {
+ assertPartlyCovered(line);
+ }
+ }
+
+ public void assertAlwaysCompletesAbruptly1(final Line line) {
+ if (isJDKCompiler) {
+ // uncovered case:
+ assertPartlyCovered(line);
+ } else {
+ assertFullyCovered(line);
+ }
+ }
+
+ @Test
+ @Override
+ public void execute_assertions_in_comments() throws IOException {
+ super.execute_assertions_in_comments();
+ gotos();
+ }
+
+ /**
+ * This test studies placement of GOTO instructions.
+ */
+ private void gotos() throws IOException {
+
+ final Set<String> expected = new HashSet<String>();
+
+ if (isJDKCompiler) {
+ expected.add("example.2");
+ } else {
+ expected.add("example.0");
+ }
+
+ expected.add("breakStatement.for");
+ if (isJDKCompiler) {
+ if (JAVA_VERSION.isBefore("10")) {
+ // https://bugs.openjdk.java.net/browse/JDK-8180141
+ expected.add("breakStatement.1");
+ } else {
+ expected.add("breakStatement");
+ }
+ expected.add("breakStatement.2");
+ } else {
+ expected.add("breakStatement");
+ }
+
+ if (isJDKCompiler) {
+ expected.add("emptyCatch.2");
+ } else {
+ expected.add("emptyCatch");
+ expected.add("emptyCatch.1");
+ }
+
+ if (isJDKCompiler) {
+ expected.add("catchNotExecuted.2");
+ } else {
+ expected.add("catchNotExecuted");
+ expected.add("catchNotExecuted.1");
+ }
+
+ if (isJDKCompiler) {
+ expected.add("nested.5");
+ expected.add("nested.6");
+ } else {
+ expected.add("nested.0");
+ expected.add("nested.3");
+ }
+
+ if (isJDKCompiler && JAVA_VERSION.isBefore("1.8")) {
+ expected.add("emptyTry.2");
+ }
+
+ if (!isJDKCompiler) {
+ expected.add("alwaysCompletesAbruptly.0");
+ }
+
+ assertEquals(expected, getTagsWithGotos());
+ }
+
+ private Set<String> getTagsWithGotos() throws IOException {
+ final Set<String> gotoTags = new HashSet<String>();
+
+ byte[] b = TargetLoader.getClassDataAsBytes(FinallyTarget.class);
+
+ final ClassNode classNode = new ClassNode();
+ InstrSupport.classReaderFor(b).accept(classNode, 0);
+ for (final MethodNode m : classNode.methods) {
+ if ("main".equals(m.name)) {
+ // skip it
+ continue;
+ }
+ int lineNumber = -1;
+ for (AbstractInsnNode i = m.instructions
+ .getFirst(); i != null; i = i.getNext()) {
+ if (AbstractInsnNode.LINE == i.getType()) {
+ lineNumber = ((LineNumberNode) i).line;
+ }
+ if (Opcodes.GOTO == i.getOpcode()) {
+ String tag = tags.get(Integer.valueOf(lineNumber));
+ if (tag == null) {
+ throw new AssertionError(
+ "No tag at line " + lineNumber);
+ }
+ gotoTags.add(tag);
+ }
+ }
+ }
+
+ return gotoTags;
+ }
+
+ public void tag(final Line line, String tag) {
+ assertFalse("duplicate tag " + tag, tags.containsValue(tag));
+ assertNull("duplicate tag in " + line,
+ tags.put(Integer.valueOf(line.getNr()), tag));
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/FramesTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/FramesTest.java
new file mode 100644
index 00000000..88e39039
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/FramesTest.java
@@ -0,0 +1,170 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.test.validation.java5;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import org.jacoco.core.instr.Instrumenter;
+import org.jacoco.core.internal.instr.InstrSupport;
+import org.jacoco.core.runtime.IRuntime;
+import org.jacoco.core.runtime.SystemPropertiesRuntime;
+import org.jacoco.core.test.TargetLoader;
+import org.jacoco.core.test.validation.java5.targets.BooleanExpressionsTarget;
+import org.jacoco.core.test.validation.java5.targets.ClassInitializerTarget;
+import org.jacoco.core.test.validation.java5.targets.ConstructorsTarget;
+import org.jacoco.core.test.validation.java5.targets.ControlStructureBeforeSuperConstructorTarget;
+import org.jacoco.core.test.validation.java5.targets.ControlStructuresTarget;
+import org.jacoco.core.test.validation.java5.targets.ExceptionsTarget;
+import org.jacoco.core.test.validation.java5.targets.ExplicitInitialFrameTarget;
+import org.jacoco.core.test.validation.java5.targets.FieldInitializationInTwoConstructorsTarget;
+import org.jacoco.core.test.validation.java5.targets.ImplicitFieldInitializationTarget;
+import org.jacoco.core.test.validation.java5.targets.InterfaceClassInitializerTarget;
+import org.jacoco.core.test.validation.java5.targets.StructuredLockingTarget;
+import org.junit.Test;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.util.TraceClassVisitor;
+
+/**
+ * Tests whether stackmap frames are correctly adjusted.
+ */
+public class FramesTest {
+
+ /**
+ * Stack sizes calculated for instrumented classes might be sometimes bigger
+ * than actually needed. This is an acceptable tradeoff in favor of keeping
+ * track of the actual stack sizes. For test assertions we need to replace
+ * max stack sizes with constant value.
+ */
+ private static class MaxStackEliminator extends ClassVisitor {
+ public MaxStackEliminator(ClassVisitor cv) {
+ super(InstrSupport.ASM_API_VERSION, cv);
+ }
+
+ @Override
+ public MethodVisitor visitMethod(int access, String name, String desc,
+ String signature, String[] exceptions) {
+ final MethodVisitor mv = super.visitMethod(access, name, desc,
+ signature, exceptions);
+ return new MethodVisitor(InstrSupport.ASM_API_VERSION, mv) {
+ @Override
+ public void visitMaxs(int maxStack, int maxLocals) {
+ super.visitMaxs(-1, maxLocals);
+ }
+ };
+ }
+ }
+
+ private void testFrames(Class<?> target) throws IOException {
+ testFrames(TargetLoader.getClassDataAsBytes(target));
+ }
+
+ private void testFrames(byte[] source) throws IOException {
+ IRuntime runtime = new SystemPropertiesRuntime();
+ Instrumenter instrumenter = new Instrumenter(runtime);
+ source = calculateFrames(source);
+ byte[] actual = instrumenter.instrument(source, "TestTarget");
+ byte[] expected = calculateFrames(actual);
+
+ assertEquals(dump(expected), dump(actual));
+ }
+
+ private byte[] calculateFrames(byte[] source) {
+ ClassReader rc = InstrSupport.classReaderFor(source);
+ ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
+
+ // Adjust Version to 1.6 to enable frames:
+ rc.accept(new ClassVisitor(InstrSupport.ASM_API_VERSION, cw) {
+
+ @Override
+ public void visit(int version, int access, String name,
+ String signature, String superName, String[] interfaces) {
+ super.visit(Opcodes.V1_6, access, name, signature, superName,
+ interfaces);
+ }
+ }, 0);
+ return cw.toByteArray();
+ }
+
+ private String dump(byte[] bytes) {
+ final StringWriter buffer = new StringWriter();
+ final PrintWriter writer = new PrintWriter(buffer);
+ new ClassReader(bytes).accept(
+ new MaxStackEliminator(new TraceClassVisitor(writer)),
+ ClassReader.EXPAND_FRAMES);
+ return buffer.toString();
+ }
+
+ @Test
+ public void boolean_expressions() throws IOException {
+ testFrames(BooleanExpressionsTarget.class);
+ }
+
+ @Test
+ public void class_initializer() throws IOException {
+ testFrames(ClassInitializerTarget.class);
+ }
+
+ @Test
+ public void constructors() throws IOException {
+ testFrames(ConstructorsTarget.class);
+ }
+
+ @Test
+ public void control_structures() throws IOException {
+ testFrames(ControlStructuresTarget.class);
+ }
+
+ @Test
+ public void control_structure_before_super_constructor()
+ throws IOException {
+ testFrames(ControlStructureBeforeSuperConstructorTarget.class);
+ }
+
+ @Test
+ public void exceptions() throws IOException {
+ testFrames(ExceptionsTarget.class);
+ }
+
+ @Test
+ public void explicit_initial_frame() throws IOException {
+ testFrames(ExplicitInitialFrameTarget.class);
+ }
+
+ @Test
+ public void field_initialization_in_two_constructors() throws IOException {
+ testFrames(FieldInitializationInTwoConstructorsTarget.class);
+ }
+
+ @Test
+ public void implicit_field_initialization() throws IOException {
+ testFrames(ImplicitFieldInitializationTarget.class);
+ }
+
+ @Test
+ public void interface_class_initializer() throws IOException {
+ testFrames(InterfaceClassInitializerTarget.class);
+ }
+
+ @Test
+ public void structured_locking() throws IOException {
+ testFrames(StructuredLockingTarget.class);
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/ImplicitFieldInitializationTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/ImplicitFieldInitializationTest.java
new file mode 100644
index 00000000..b46e9c22
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/ImplicitFieldInitializationTest.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.test.validation.java5;
+
+import org.jacoco.core.test.validation.ValidationTestBase;
+import org.jacoco.core.test.validation.java5.targets.ImplicitFieldInitializationTarget;
+
+/**
+ * Test of a implicit field initialization.
+ */
+public class ImplicitFieldInitializationTest extends ValidationTestBase {
+
+ public ImplicitFieldInitializationTest() {
+ super(ImplicitFieldInitializationTarget.class);
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/InterfaceClassInitializerTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/InterfaceClassInitializerTest.java
new file mode 100644
index 00000000..ed4843b1
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/InterfaceClassInitializerTest.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.test.validation.java5;
+
+import org.jacoco.core.test.validation.ValidationTestBase;
+import org.jacoco.core.test.validation.java5.targets.InterfaceClassInitializerTarget;
+
+/**
+ * Tests of static initializer in interfaces.
+ */
+public class InterfaceClassInitializerTest extends ValidationTestBase {
+
+ public InterfaceClassInitializerTest() {
+ super(InterfaceClassInitializerTarget.class);
+ }
+
+ @Override
+ protected void run(final Class<?> targetClass) throws Exception {
+ // Force class initialization
+ targetClass.getField("CONST1").get(null);
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/StructuredLockingTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/StructuredLockingTest.java
new file mode 100644
index 00000000..7e13e651
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/StructuredLockingTest.java
@@ -0,0 +1,196 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.test.validation.java5;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.jacoco.core.instr.Instrumenter;
+import org.jacoco.core.internal.instr.InstrSupport;
+import org.jacoco.core.runtime.IRuntime;
+import org.jacoco.core.runtime.SystemPropertiesRuntime;
+import org.jacoco.core.test.TargetLoader;
+import org.jacoco.core.test.validation.java5.targets.StructuredLockingTarget;
+import org.junit.Test;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.ClassNode;
+import org.objectweb.asm.tree.MethodNode;
+import org.objectweb.asm.tree.TryCatchBlockNode;
+import org.objectweb.asm.tree.VarInsnNode;
+import org.objectweb.asm.tree.analysis.Analyzer;
+import org.objectweb.asm.tree.analysis.AnalyzerException;
+import org.objectweb.asm.tree.analysis.BasicInterpreter;
+import org.objectweb.asm.tree.analysis.BasicValue;
+import org.objectweb.asm.tree.analysis.Frame;
+import org.objectweb.asm.tree.analysis.Interpreter;
+
+/**
+ * Tests that the invariants specified in <a href=
+ * "https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-2.html#jvms-2.11.10">chapter
+ * 2.11.10 of the JVM Spec</a> do also hold for instrumented classes.
+ *
+ * This is important because JIT compiler in HotSpot JVM ignores methods with
+ * unstructured locking, so that they executed by interpreter. Android Runtime
+ * also doesn't optimize such methods.
+ *
+ * TODO verification implemented here is incomplete - in particular it is unable
+ * to catch problem described in https://github.com/jacoco/jacoco/issues/626
+ */
+public class StructuredLockingTest {
+
+ @Test
+ public void testMonitorExit() throws Exception {
+ assertStructuredLocking(TargetLoader
+ .getClassDataAsBytes(StructuredLockingTarget.class));
+ }
+
+ private void assertStructuredLocking(byte[] source) throws Exception {
+ IRuntime runtime = new SystemPropertiesRuntime();
+ Instrumenter instrumenter = new Instrumenter(runtime);
+ byte[] instrumented = instrumenter.instrument(source, "TestTarget");
+
+ ClassNode cn = new ClassNode();
+ InstrSupport.classReaderFor(instrumented).accept(cn, 0);
+ for (MethodNode mn : cn.methods) {
+ assertStructuredLocking(cn.name, mn);
+ }
+ }
+
+ private void assertStructuredLocking(String owner, MethodNode mn)
+ throws Exception {
+ Analyzer<BasicValue> analyzer = new Analyzer<BasicValue>(
+ new BasicInterpreter()) {
+
+ @Override
+ protected Frame<BasicValue> newFrame(int nLocals, int nStack) {
+ return new LockFrame(nLocals, nStack);
+ }
+
+ @Override
+ protected Frame<BasicValue> newFrame(
+ Frame<? extends BasicValue> src) {
+ return new LockFrame(src);
+ }
+ };
+
+ Frame<BasicValue>[] frames = analyzer.analyze(owner, mn);
+
+ // Make sure no locks are left when method exits:
+ for (int i = 0; i < frames.length; i++) {
+ AbstractInsnNode insn = mn.instructions.get(i);
+ switch (insn.getOpcode()) {
+ case Opcodes.IRETURN:
+ case Opcodes.LRETURN:
+ case Opcodes.FRETURN:
+ case Opcodes.DRETURN:
+ case Opcodes.ARETURN:
+ case Opcodes.RETURN:
+ ((LockFrame) frames[i]).assertNoLock("Exit with lock");
+ break;
+ case Opcodes.ATHROW:
+ List<TryCatchBlockNode> handlers = analyzer.getHandlers(i);
+ if (handlers == null || handlers.isEmpty()) {
+ ((LockFrame) frames[i]).assertNoLock("Exit with lock");
+ }
+ break;
+ }
+ }
+
+ // Only instructions protected by a catch-all handler can hold locks:
+ for (int i = 0; i < frames.length; i++) {
+ AbstractInsnNode insn = mn.instructions.get(i);
+ if (insn.getOpcode() > 0) {
+ boolean catchAll = false;
+ List<TryCatchBlockNode> handlers = analyzer.getHandlers(i);
+ if (handlers != null) {
+ for (TryCatchBlockNode node : handlers) {
+ catchAll |= node.type == null;
+ }
+ }
+ if (!catchAll) {
+ ((LockFrame) frames[i])
+ .assertNoLock("No handlers for insn with lock");
+ }
+ }
+ }
+
+ }
+
+ /**
+ * A Frame implementation that keeps track of the locking state. It is
+ * assumed that the monitor objects are stored in local variables.
+ */
+ private static class LockFrame extends Frame<BasicValue> {
+
+ Set<Integer> locks;
+
+ public LockFrame(final int nLocals, final int nStack) {
+ super(nLocals, nStack);
+ locks = new HashSet<Integer>();
+ }
+
+ public LockFrame(Frame<? extends BasicValue> src) {
+ super(src);
+ }
+
+ @Override
+ public Frame<BasicValue> init(Frame<? extends BasicValue> src) {
+ locks = new HashSet<Integer>(((LockFrame) src).locks);
+ return super.init(src);
+ }
+
+ @Override
+ public void execute(AbstractInsnNode insn,
+ Interpreter<BasicValue> interpreter) throws AnalyzerException {
+ super.execute(insn, interpreter);
+ switch (insn.getOpcode()) {
+ case Opcodes.MONITORENTER:
+ // Lock is stored in a local variable:
+ enter(((VarInsnNode) insn.getPrevious()).var);
+ break;
+ case Opcodes.MONITOREXIT:
+ // Lock is stored in a local variable:
+ exit(((VarInsnNode) insn.getPrevious()).var);
+ break;
+ }
+ }
+
+ void enter(int lock) {
+ assertTrue("multiple ENTER for lock " + lock,
+ locks.add(Integer.valueOf(lock)));
+ }
+
+ void exit(int lock) {
+ assertTrue("invalid EXIT for lock " + lock,
+ locks.remove(Integer.valueOf(lock)));
+ }
+
+ @Override
+ public boolean merge(Frame<? extends BasicValue> frame,
+ Interpreter<BasicValue> interpreter) throws AnalyzerException {
+ this.locks.addAll(((LockFrame) frame).locks);
+ return super.merge(frame, interpreter);
+ }
+
+ void assertNoLock(String message) {
+ assertEquals(message, Collections.emptySet(), locks);
+
+ }
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/SynchronizedTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/SynchronizedTest.java
new file mode 100644
index 00000000..e4a841d8
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/SynchronizedTest.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.java5;
+
+import org.jacoco.core.test.validation.Source.Line;
+import org.jacoco.core.test.validation.ValidationTestBase;
+import org.jacoco.core.test.validation.java5.targets.SynchronizedTarget;
+
+/**
+ * Test of filtering of a bytecode that is generated for a synchronized
+ * statement.
+ */
+public class SynchronizedTest extends ValidationTestBase {
+
+ public SynchronizedTest() {
+ super(SynchronizedTarget.class);
+ }
+
+ public void assertMonitorEnterImplicitException(final Line line) {
+ if (isJDKCompiler) {
+ assertFullyCovered(line);
+ } else {
+ assertPartlyCovered(line);
+ }
+ }
+
+ public void assertMonitorExit(final Line line) {
+ if (isJDKCompiler) {
+ // without filter next line covered partly:
+ assertFullyCovered(line);
+ } else {
+ assertEmpty(line);
+ }
+ }
+
+ public void assertMonitorExitImplicitException(final Line line) {
+ if (isJDKCompiler) {
+ // without filter next line covered partly:
+ assertNotCovered(line);
+ } else {
+ assertEmpty(line);
+ }
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/SyntheticTest.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/SyntheticTest.java
new file mode 100644
index 00000000..ce690bfc
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/SyntheticTest.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.java5;
+
+import org.jacoco.core.test.validation.ValidationTestBase;
+import org.jacoco.core.test.validation.java5.targets.SyntheticTarget;
+
+/**
+ * Test of filtering of synthetic methods.
+ */
+public class SyntheticTest extends ValidationTestBase {
+
+ public SyntheticTest() {
+ super(SyntheticTarget.class);
+ }
+
+ public void test_method_count() {
+ assertMethodCount(5);
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/AnnotationGeneratedTarget.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/AnnotationGeneratedTarget.java
new file mode 100644
index 00000000..7effe60c
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/AnnotationGeneratedTarget.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.java5.targets;
+
+import static org.jacoco.core.test.validation.targets.Stubs.nop;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+public class AnnotationGeneratedTarget {
+
+ private static class RetentionPolicyRuntime {
+
+ @Retention(RetentionPolicy.RUNTIME)
+ @interface Generated {
+ }
+
+ @RetentionPolicyRuntime.Generated
+ static void annotatedMethod() {
+ nop(); // assertEmpty()
+ }
+
+ @RetentionPolicyRuntime.Generated
+ static class AnnotatedClass {
+ AnnotatedClass() {
+ nop(); // assertEmpty()
+ }
+ }
+
+ }
+
+ private static class RetentionPolicyClass {
+
+ @Retention(RetentionPolicy.CLASS)
+ @interface Generated {
+ }
+
+ @RetentionPolicyClass.Generated
+ static void annotatedMethod() {
+ nop(); // assertEmpty()
+ }
+
+ @RetentionPolicyClass.Generated
+ static class AnnotatedClass {
+ AnnotatedClass() {
+ nop(); // assertEmpty()
+ }
+ }
+
+ }
+
+ private static class RetentionPolicySource {
+
+ @Retention(RetentionPolicy.SOURCE)
+ @interface Generated {
+ }
+
+ @RetentionPolicySource.Generated
+ static void annotatedMethod() {
+ nop(); // assertFullyCovered()
+ }
+
+ @RetentionPolicySource.Generated
+ static class AnnotatedClass {
+ AnnotatedClass() {
+ nop(); // assertFullyCovered()
+ }
+ }
+
+ }
+
+ public static void main(String[] args) {
+ RetentionPolicyRuntime.annotatedMethod();
+ new RetentionPolicyRuntime.AnnotatedClass();
+
+ RetentionPolicyClass.annotatedMethod();
+ new RetentionPolicyClass.AnnotatedClass();
+
+ RetentionPolicySource.annotatedMethod();
+ new RetentionPolicySource.AnnotatedClass();
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/AnnotationInitializerTarget.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/AnnotationInitializerTarget.java
new file mode 100644
index 00000000..841f0961
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/AnnotationInitializerTarget.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.java5.targets;
+
+/**
+ * This test target is an annotation with an initializer.
+ */
+public @interface AnnotationInitializerTarget {
+
+ Object CONST = new Object(); // assertFullyCovered()
+
+ int value() default 0; // assertEmpty()
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/BadCycleClassTarget.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/BadCycleClassTarget.java
new file mode 100644
index 00000000..c37fa8aa
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/BadCycleClassTarget.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.java5.targets;
+
+import org.jacoco.core.test.validation.targets.Stubs;
+
+public class BadCycleClassTarget {
+
+ public static class Base {
+ static final Child b = new Child();
+
+ static {
+ b.someMethod();
+ }
+ }
+
+ public static class Child extends Base {
+
+ static {
+ Stubs.logEvent("childclinit"); // assertFullyCovered()
+ }
+
+ public Child() {
+ Stubs.logEvent("childinit"); // assertFullyCovered()
+ }
+
+ void someMethod() {
+ Stubs.logEvent("childsomeMethod"); // assertFullyCovered()
+ }
+
+ }
+
+ public static void main(String[] args) {
+ new Child();
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/BooleanExpressionsTarget.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/BooleanExpressionsTarget.java
new file mode 100644
index 00000000..6015ceac
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/BooleanExpressionsTarget.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.test.validation.java5.targets;
+
+import static org.jacoco.core.test.validation.targets.Stubs.f;
+import static org.jacoco.core.test.validation.targets.Stubs.i1;
+import static org.jacoco.core.test.validation.targets.Stubs.i2;
+import static org.jacoco.core.test.validation.targets.Stubs.nop;
+import static org.jacoco.core.test.validation.targets.Stubs.t;
+
+/**
+ * This target exercises boolean expressions.
+ */
+public class BooleanExpressionsTarget {
+
+ public static void main(String[] args) {
+
+ /* 1. Boolean comparison result (one case) */
+ nop(i2() > 3); // assertPartlyCovered(1, 1)
+
+ /* 2. Boolean comparison result (both cases) */
+ for (int i = 0; i < 2; i++) {
+ nop(i < 1); // assertFullyCovered(0, 2)
+ }
+
+ /* 3. And */
+ if (f() & f()) { // assertFullyCovered(1, 1)
+ nop();
+ }
+ if (f() & t()) { // assertFullyCovered(1, 1)
+ nop();
+ }
+ if (t() & f()) { // assertFullyCovered(1, 1)
+ nop();
+ }
+ if (t() & t()) { // assertFullyCovered(1, 1)
+ nop();
+ }
+
+ /* 4. Conditional And */
+ if (f() && f()) { // assertPartlyCovered(3, 1)
+ nop();
+ }
+ if (f() && t()) { // assertPartlyCovered(3, 1)
+ nop();
+ }
+ if (t() && f()) { // assertFullyCovered(2, 2)
+ nop();
+ }
+ if (t() && t()) { // assertFullyCovered(2, 2)
+ nop();
+ }
+
+ /* 5. Or */
+ if (f() | f()) { // assertFullyCovered(1, 1)
+ nop();
+ }
+ if (f() | t()) { // assertFullyCovered(1, 1)
+ nop();
+ }
+ if (t() | f()) { // assertFullyCovered(1, 1)
+ nop();
+ }
+ if (t() | t()) { // assertFullyCovered(1, 1)
+ nop();
+ }
+
+ /* 6. Conditional Or */
+ if (f() || f()) { // assertFullyCovered(2, 2)
+ nop();
+ }
+ if (f() || t()) { // assertFullyCovered(2, 2)
+ nop();
+ }
+ if (t() || f()) { // assertPartlyCovered(3, 1)
+ nop();
+ }
+ if (t() || t()) { // assertPartlyCovered(3, 1)
+ nop();
+ }
+
+ /* 7. Exclusive Or */
+ if (f() ^ f()) { // assertFullyCovered(1, 1)
+ nop();
+ }
+ if (f() ^ t()) { // assertFullyCovered(1, 1)
+ nop();
+ }
+ if (t() ^ f()) { // assertFullyCovered(1, 1)
+ nop();
+ }
+ if (t() ^ t()) { // assertFullyCovered(1, 1)
+ nop();
+ }
+
+ /* 8. Conditional Operator */
+ nop(t() ? i1() : i2()); // assertPartlyCovered(1, 1)
+ nop(f() ? i1() : i2()); // assertPartlyCovered(1, 1)
+
+ /* 9. Not (one case) */
+ nop(!t()); // assertPartlyCovered(1, 1)
+ nop(!f()); // assertPartlyCovered(1, 1)
+
+ /* 10. Not (both cases) */
+ for (boolean b : new boolean[] { true, false }) {
+ nop(!b); // assertFullyCovered(0, 2)
+ }
+
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/ClassInitializerTarget.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/ClassInitializerTarget.java
new file mode 100644
index 00000000..5b1f5543
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/ClassInitializerTarget.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.test.validation.java5.targets;
+
+import static org.jacoco.core.test.validation.targets.Stubs.i1;
+
+import org.jacoco.core.test.validation.targets.Stubs;
+
+/**
+ * This test target is a class with a static initializer.
+ */
+public class ClassInitializerTarget {
+
+ /* No code required to initialize these fields: */
+
+ public static final int CONST1 = 3; // assertEmpty()
+
+ public static final String CONST2 = "Hello"; // assertEmpty()
+
+ /* These fields are initialized within <clinit> */
+
+ public static final int CONST3 = i1(); // assertFullyCovered()
+
+ public static final Object CONST4 = new Object(); // assertFullyCovered()
+
+ public static int field1 = 3; // assertFullyCovered()
+
+ public static String field2 = "Hello"; // assertFullyCovered()
+
+ public static int field3 = i1(); // assertFullyCovered()
+
+ public static Object field4 = new Object(); // assertFullyCovered()
+
+ static {
+ Stubs.nop(); // assertFullyCovered()
+ }
+
+ private ClassInitializerTarget() {
+ }
+
+ public static void main(String[] args) {
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/ConstructorsTarget.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/ConstructorsTarget.java
new file mode 100644
index 00000000..f818440e
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/ConstructorsTarget.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.java5.targets;
+
+import static org.jacoco.core.test.validation.targets.Stubs.nop;
+
+/**
+ * This test target calls different constructors.
+ */
+public class ConstructorsTarget {
+
+ /* not filtered because not private: */
+ ConstructorsTarget() { // assertFullyCovered()
+ }
+
+ /* not filtered because has argument: */
+ private ConstructorsTarget(Object arg) { // assertFullyCovered()
+ }
+
+ private static class Super extends ConstructorsTarget {
+ private Super() {
+ /*
+ * not filtered because not empty - prepares arguments for super
+ * constructor:
+ */
+ super(null); // assertFullyCovered()
+ }
+ }
+
+ private class Inner {
+ /*
+ * not filtered because contains initialization of a field to hold
+ * reference to an instance of outer class that is passed as an
+ * argument:
+ */
+ private Inner() { // assertFullyCovered()
+ }
+ }
+
+ private static class InnerStatic {
+ @SuppressWarnings("unused")
+ private final Object field = this;
+
+ /*
+ * not filtered because not empty - contains initialization of a field:
+ */
+ private InnerStatic() { // assertFullyCovered()
+ }
+ }
+
+ /*
+ * not filtered because default constructor for not private inner classes is
+ * not private:
+ */
+ public static class PublicDefault { // assertFullyCovered()
+ }
+
+ static class PackageLocalDefault { // assertFullyCovered()
+ }
+
+ private static class PrivateDefault { // assertEmpty()
+ }
+
+ private static class PrivateNonEmptyNoArg {
+ private PrivateNonEmptyNoArg() {
+ nop(); // assertFullyCovered()
+ }
+ }
+
+ private static class PrivateEmptyNoArg {
+ private PrivateEmptyNoArg() { // assertEmpty()
+ } // assertEmpty()
+ }
+
+ public static void main(String[] args) {
+ new Super();
+ new ConstructorsTarget().new Inner();
+ new InnerStatic();
+ new PublicDefault();
+ new PackageLocalDefault();
+ new PrivateDefault();
+ new PrivateNonEmptyNoArg();
+ new PrivateEmptyNoArg();
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/ControlStructureBeforeSuperConstructorTarget.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/ControlStructureBeforeSuperConstructorTarget.java
new file mode 100644
index 00000000..3af40473
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/ControlStructureBeforeSuperConstructorTarget.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.test.validation.java5.targets;
+
+import static org.jacoco.core.test.validation.targets.Stubs.f;
+import static org.jacoco.core.test.validation.targets.Stubs.t;
+
+import org.jacoco.core.test.validation.targets.Stubs.SuperClass;
+
+/**
+ * This test target has a constructor containing control structures before the
+ * superclass constructor is called.
+ */
+public class ControlStructureBeforeSuperConstructorTarget extends SuperClass {
+
+ public ControlStructureBeforeSuperConstructorTarget() {
+ super(t() || f()); // assertPartlyCovered(3, 1)
+ }
+
+ public static void main(String[] args) {
+ new ControlStructureBeforeSuperConstructorTarget();
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/ControlStructuresTarget.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/ControlStructuresTarget.java
new file mode 100644
index 00000000..571adca1
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/ControlStructuresTarget.java
@@ -0,0 +1,293 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.test.validation.java5.targets;
+
+import static org.jacoco.core.test.validation.targets.Stubs.f;
+import static org.jacoco.core.test.validation.targets.Stubs.i2;
+import static org.jacoco.core.test.validation.targets.Stubs.nop;
+import static org.jacoco.core.test.validation.targets.Stubs.t;
+
+import java.util.Collections;
+
+/**
+ * This target exercises a set of common Java control structures.
+ */
+public class ControlStructuresTarget {
+
+ public static void main(String[] args) {
+
+ unconditionalExecution();
+ missedIfBlock();
+ executedIfBlock();
+ missedWhileBlock();
+ alwaysExecutedWhileBlock();
+ executedWhileBlock();
+ executedDoWhileBlock();
+ missedForBlock();
+ executedForBlock();
+ missedForEachBlock();
+ executedForEachBlock();
+ tableSwitchWithHit();
+ continuedTableSwitchWithHit();
+ tableSwitchWithoutHit();
+ lookupSwitchWithHit();
+ continuedLookupSwitchWithHit();
+ lookupSwitchWithoutHit();
+ breakStatement();
+ continueStatement();
+ conditionalReturn();
+ implicitReturn();
+ explicitReturn();
+
+ }
+
+ private static void unconditionalExecution() {
+
+ nop(); // assertFullyCovered()
+
+ }
+
+ private static void missedIfBlock() {
+
+ if (f()) { // assertFullyCovered(1, 1)
+ nop(); // assertNotCovered()
+ } else {
+ nop(); // assertFullyCovered()
+ }
+
+ }
+
+ private static void executedIfBlock() {
+
+ if (t()) { // assertFullyCovered(1, 1)
+ nop(); // assertFullyCovered()
+ } else {
+ nop(); // assertNotCovered()
+ }
+
+ }
+
+ private static void missedWhileBlock() {
+
+ while (f()) { // assertFullyCovered(1, 1)
+ nop(); // assertNotCovered()
+ }
+
+ }
+
+ private static void alwaysExecutedWhileBlock() {
+
+ while (t()) { // assertFullyCovered(1, 1)
+ if (t()) {
+ break;
+ }
+ }
+
+ }
+
+ private static void executedWhileBlock() {
+
+ int i = 0;
+ while (i++ < 3) { // assertFullyCovered(0, 2)
+ nop(); // assertFullyCovered()
+ }
+
+ }
+
+ private static void executedDoWhileBlock() {
+
+ do {
+ nop(); // assertFullyCovered()
+ } while (f()); // assertFullyCovered(1, 1)
+
+ }
+
+ private static void missedForBlock() {
+
+ for (nop(); f(); nop()) { // assertPartlyCovered(1, 1)
+ nop(); // assertNotCovered()
+ }
+
+ }
+
+ private static void executedForBlock() {
+
+ for (int j = 0; j < 1; j++) { // assertFullyCovered(0, 2)
+ nop(); // assertFullyCovered()
+ }
+
+ }
+
+ private static void missedForEachBlock() {
+
+ for (Object o : Collections.emptyList()) { // assertPartlyCovered(1, 1)
+ nop(o); // assertNotCovered()
+ }
+
+ }
+
+ private static void executedForEachBlock() {
+
+ for (Object o : Collections.singleton(new Object())) { // assertFullyCovered(0,2)
+ nop(o); // assertFullyCovered()
+ }
+
+ }
+
+ private static void tableSwitchWithHit() {
+
+ switch (i2()) { // assertFullyCovered(3, 1)
+ case 1:
+ nop(); // assertNotCovered()
+ break;
+ case 2:
+ nop(); // assertFullyCovered()
+ break;
+ case 3:
+ nop(); // assertNotCovered()
+ break;
+ default:
+ nop(); // assertNotCovered()
+ break;
+ }
+
+ }
+
+ private static void continuedTableSwitchWithHit() {
+
+ switch (i2()) { // assertFullyCovered(3, 1)
+ case 1:
+ nop(); // assertNotCovered()
+ case 2:
+ nop(); // assertFullyCovered()
+ case 3:
+ nop(); // assertFullyCovered()
+ default:
+ nop(); // assertFullyCovered()
+ }
+
+ }
+
+ private static void tableSwitchWithoutHit() {
+
+ switch (i2()) { // assertFullyCovered(3, 1)
+ case 3:
+ nop(); // assertNotCovered()
+ break;
+ case 4:
+ nop(); // assertNotCovered()
+ break;
+ case 5:
+ nop(); // assertNotCovered()
+ break;
+ default:
+ nop(); // assertFullyCovered()
+ break;
+ }
+
+ }
+
+ private static void lookupSwitchWithHit() {
+
+ switch (i2()) { // assertFullyCovered(3, 1)
+ case -123:
+ nop(); // assertNotCovered()
+ break;
+ case 2:
+ nop(); // assertFullyCovered()
+ break;
+ case 456:
+ nop(); // assertNotCovered()
+ break;
+ default:
+ nop(); // assertNotCovered()
+ break;
+ }
+
+ }
+
+ private static void continuedLookupSwitchWithHit() {
+
+ switch (i2()) { // assertFullyCovered(3, 1)
+ case -123:
+ nop(); // assertNotCovered()
+ case 2:
+ nop(); // assertFullyCovered()
+ case 456:
+ nop(); // assertFullyCovered()
+ default:
+ nop(); // assertFullyCovered()
+ }
+
+ }
+
+ private static void lookupSwitchWithoutHit() {
+
+ switch (i2()) { // assertFullyCovered(3, 1)
+ case -123:
+ nop(); // assertNotCovered()
+ break;
+ case 456:
+ nop(); // assertNotCovered()
+ break;
+ case 789:
+ nop(); // assertNotCovered()
+ break;
+ default:
+ nop(); // assertFullyCovered()
+ break;
+ }
+
+ }
+
+ private static void breakStatement() {
+
+ while (true) {
+ if (t()) {
+ break; // assertFullyCovered()
+ }
+ nop(); // assertNotCovered()
+ }
+
+ }
+
+ private static void continueStatement() {
+
+ for (int j = 0; j < 1; j++) {
+ if (t()) {
+ continue; // assertFullyCovered()
+ }
+ nop(); // assertNotCovered()
+ }
+
+ }
+
+ private static void conditionalReturn() {
+
+ if (t()) {
+ return; // assertFullyCovered()
+ }
+ nop(); // assertNotCovered()
+
+ }
+
+ private static void implicitReturn() {
+
+ } // assertFullyCovered()
+
+ private static void explicitReturn() {
+
+ return; // assertFullyCovered()
+
+ } // assertEmpty()
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/EnumConstructorTarget.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/EnumConstructorTarget.java
new file mode 100644
index 00000000..5b526b94
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/EnumConstructorTarget.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.java5.targets;
+
+import static org.jacoco.core.test.validation.targets.Stubs.nop;
+
+/**
+ * This test target is an enum constructor.
+ */
+public class EnumConstructorTarget {
+
+ /*
+ * Implicit constructor should be filtered. without filter next line is
+ * partly covered:
+ */
+ private enum ImplicitConstructor { // assertFullyCovered()
+ }
+
+ /* Explicit non empty constructor should not be filtered: */
+ private enum ExplicitNonEmptyConstructor {
+ ;
+
+ ExplicitNonEmptyConstructor() {
+ nop(); // assertNotCovered()
+ }
+ }
+
+ /* Explicit empty constructor should be filtered: */
+ private enum ExplicitEmptyConstructor {
+ ;
+
+ ExplicitEmptyConstructor() {
+ /* without filter next line is not covered: */
+ } // assertEmpty()
+
+ ExplicitEmptyConstructor(Object p) {
+ } // assertNotCovered()
+ }
+
+ public static void main(String[] args) {
+ ImplicitConstructor.values();
+ ExplicitEmptyConstructor.values();
+ ExplicitNonEmptyConstructor.values();
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/EnumImplicitMethodsTarget.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/EnumImplicitMethodsTarget.java
new file mode 100644
index 00000000..687bc4ec
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/EnumImplicitMethodsTarget.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.java5.targets;
+
+import org.jacoco.core.test.validation.targets.Stubs;
+
+public enum EnumImplicitMethodsTarget { // assertFullyCovered()
+
+ CONST(Stubs.f() ? new Object() : new Object()); // assertPartlyCovered(1, 1)
+
+ static {
+ } // assertFullyCovered()
+
+ /**
+ * Unlike in {@link ConstructorsTarget regular classes}, even if enum has
+ * explicit constructor, {@code clinit} method in any case has a reference
+ * to the line of enum definition.
+ */
+ EnumImplicitMethodsTarget(Object o) { // assertFullyCovered()
+ } // assertFullyCovered()
+
+ /**
+ * This method should not be excluded from analysis unlike implicitly
+ * created {@link #valueOf(String)} method that refers to the line of enum
+ * definition in case of javac and to the first line in case of ECJ.
+ */
+ public void valueOf() {
+ } // assertNotCovered()
+
+ /**
+ * This method should not be excluded from analysis unlike implicitly
+ * created {@link #values()} method that refers to the line of enum
+ * definition in case of javac and to the first line in case of ECJ.
+ */
+ public void values(Object o) {
+ } // assertNotCovered()
+
+ public static void main(String[] args) {
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/EnumSwitchTarget.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/EnumSwitchTarget.java
new file mode 100644
index 00000000..51ca47e4
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/EnumSwitchTarget.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.java5.targets;
+
+import static org.jacoco.core.test.validation.targets.Stubs.nop;
+
+/**
+ * This test target is a switch statement with a enum.
+ */
+public class EnumSwitchTarget {
+
+ private enum E {
+ V1, V2
+ }
+
+ private static void example(E e) {
+ switch (e) { // assertSwitch()
+ case V1:
+ nop("V1");
+ break;
+ case V2:
+ default:
+ nop("V2");
+ break;
+ }
+ }
+
+ public static void main(String[] args) {
+ example(E.V1);
+ example(E.V2);
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/ExceptionsTarget.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/ExceptionsTarget.java
new file mode 100644
index 00000000..efac5a69
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/ExceptionsTarget.java
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.test.validation.java5.targets;
+
+import static org.jacoco.core.test.validation.targets.Stubs.ex;
+import static org.jacoco.core.test.validation.targets.Stubs.f;
+import static org.jacoco.core.test.validation.targets.Stubs.nop;
+
+import org.jacoco.core.test.validation.targets.Stubs.StubException;
+
+/**
+ * This target produces exception based control flow examples.
+ */
+public class ExceptionsTarget {
+
+ public static void main(String[] args) {
+
+ try {
+ implicitNullPointerException(null);
+ } catch (NullPointerException e) {
+ }
+ try {
+ implicitException();
+ } catch (StubException e) {
+ }
+ try {
+ explicitException();
+ } catch (StubException e) {
+ }
+ noExceptionTryCatch();
+ implicitExceptionTryCatch();
+ implicitExceptionTryCatchAfterCondition();
+ explicitExceptionTryCatch();
+ noExceptionFinally();
+ try {
+ explicitExceptionFinally();
+ } catch (StubException e) {
+ }
+ try {
+ implicitExceptionFinally();
+ } catch (StubException e) {
+ }
+ }
+
+ /**
+ * Currently no coverage at all, as we don't see when a block aborts
+ * somewhere in the middle.
+ */
+ private static void implicitNullPointerException(int[] a) {
+ nop(); // assertNotCovered()
+ a[0] = 0; // assertNotCovered()
+ nop(); // assertNotCovered()
+ }
+
+ /**
+ * For each line with method invocations a extra probe is inserted.
+ * Therefore the lines before the exception are marked as covered.
+ */
+ private static void implicitException() {
+ nop(); // assertFullyCovered()
+ ex(); // assertNotCovered()
+ nop(); // assertNotCovered()
+ }
+
+ private static void explicitException() {
+ nop(); // assertFullyCovered()
+ throw new StubException(); // assertFullyCovered()
+ }
+
+ private static void noExceptionTryCatch() {
+ nop(); // assertFullyCovered()
+ try {
+ nop(); // assertFullyCovered()
+ } catch (StubException e) { // assertCatchNoException()
+ nop(); // assertNotCovered()
+ } // assertCatchBlockEndNoException()
+ } // assertFullyCovered()
+
+ private static void implicitExceptionTryCatch() {
+ nop(); // assertFullyCovered()
+ try {
+ nop(); // assertFullyCovered()
+ ex(); // assertNotCovered()
+ nop(); // assertNotCovered()
+ } catch (StubException e) { // assertCatchImplicitException()
+ nop(); // assertFullyCovered()
+ } // assertCatchBlockEndImplicitException()
+ } // assertFullyCovered()
+
+ /**
+ * As the try/catch block is entered at one branch of the condition should
+ * be marked as executed
+ */
+ private static void implicitExceptionTryCatchAfterCondition() {
+ if (f()) { // assertFullyCovered(1, 1)
+ return;
+ }
+ try {
+ ex(); // assertNotCovered()
+ } catch (StubException e) {
+ nop(); // assertFullyCovered()
+ }
+ }
+
+ private static void explicitExceptionTryCatch() {
+ nop(); // assertFullyCovered()
+ try {
+ nop(); // assertFullyCovered()
+ throw new StubException(); // assertFullyCovered()
+ } catch (StubException e) { // assertFullyCovered()
+ nop(); // assertFullyCovered()
+ } // assertEmpty()
+ } // assertFullyCovered()
+
+ private static void noExceptionFinally() {
+ nop(); // assertFullyCovered()
+ try {
+ nop(); // assertFullyCovered()
+ } finally { // assertFinally()
+ nop(); // assertFullyCovered()
+ } // assertEmpty()
+ } // assertFullyCovered()
+
+ private static void implicitExceptionFinally() {
+ nop(); // assertFullyCovered()
+ try {
+ nop(); // assertFullyCovered()
+ ex(); // assertNotCovered()
+ nop(); // assertNotCovered()
+ } finally { // assertFinallyImplicitException()
+ nop(); // assertFullyCovered()
+ } // assertEmpty()
+ } // assertNotCovered()
+
+ private static void explicitExceptionFinally() {
+ nop(); // assertFullyCovered()
+ try {
+ nop(); // assertFullyCovered()
+ throw new StubException(); // assertFullyCovered()
+ } finally { // assertFinally()
+ nop(); // assertFullyCovered()
+ } // assertBlockEndImplicitException()
+ } // assertEmpty()
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/ExplicitInitialFrameTarget.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/ExplicitInitialFrameTarget.java
new file mode 100644
index 00000000..475de0a4
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/ExplicitInitialFrameTarget.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.test.validation.java5.targets;
+
+import static org.jacoco.core.test.validation.targets.Stubs.f;
+import static org.jacoco.core.test.validation.targets.Stubs.nop;
+
+/**
+ * This test target needs an explicit initial frame as the first instruction
+ * already is a jump target.
+ */
+public class ExplicitInitialFrameTarget {
+
+ public static void main(String[] args) {
+
+ do {
+ nop(); // assertFullyCovered()
+ } while (f());
+
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/FieldInitializationInTwoConstructorsTarget.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/FieldInitializationInTwoConstructorsTarget.java
new file mode 100644
index 00000000..b79b9224
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/FieldInitializationInTwoConstructorsTarget.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.test.validation.java5.targets;
+
+/**
+ * This test target has instance members with initialization in two
+ * constructors.
+ */
+public class FieldInitializationInTwoConstructorsTarget {
+
+ Object field1 = null; // assertPartlyCovered()
+
+ int field2 = 123; // assertPartlyCovered()
+
+ public FieldInitializationInTwoConstructorsTarget() {
+ } // assertFullyCovered()
+
+ public FieldInitializationInTwoConstructorsTarget(String arg) {
+ } // assertNotCovered()
+
+ public static void main(String[] args) {
+ new FieldInitializationInTwoConstructorsTarget();
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/FinallyTarget.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/FinallyTarget.java
new file mode 100644
index 00000000..66aeabec
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/FinallyTarget.java
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.java5.targets;
+
+import static org.jacoco.core.test.validation.targets.Stubs.ex;
+import static org.jacoco.core.test.validation.targets.Stubs.f;
+import static org.jacoco.core.test.validation.targets.Stubs.nop;
+import static org.jacoco.core.test.validation.targets.Stubs.t;
+
+public class FinallyTarget {
+
+ /**
+ * <pre>
+ * InputStream in = null;
+ * try {
+ * in = ...;
+ * ...
+ * } finally {
+ * if (in != null) {
+ * in.close();
+ * }
+ * }
+ * </pre>
+ */
+ private static void example(boolean t) {
+ Object in = null;
+ try {
+ in = open(t);
+ } finally { // assertFinally() tag("example.0")
+ if (in != null) { // assertFullyCovered(0, 2)
+ nop(); // assertFullyCovered() tag("example.2")
+ } // assertEmpty()
+ } // assertEmpty()
+ }
+
+ private static Object open(boolean t) {
+ ex(t);
+ return new Object();
+ }
+
+ /**
+ * GOTO instructions at the end of duplicates of finally block might have
+ * line number of a last instruction of finally block and hence lead to
+ * unexpected coverage results, like for example in case of ECJ for
+ * {@link FinallyTarget#catchNotExecuted()},
+ * {@link FinallyTarget#emptyCatch()}. So we decided to ignore them, even if
+ * they can correspond to a real break statement.
+ * <p>
+ * See also <a href=
+ * "https://bugs.openjdk.java.net/browse/JDK-8180141">JDK-8180141</a> and
+ * <a href=
+ * "https://bugs.openjdk.java.net/browse/JDK-7008643">JDK-7008643</a>.
+ */
+ private static void breakStatement() {
+ for (int i = 0; i < 1; i++) { // tag("breakStatement.for")
+ try {
+ if (f()) {
+ break; // assertEmpty() tag("breakStatement")
+ }
+ } finally {
+ nop("finally"); // assertFullyCovered() tag("breakStatement.1")
+ } // assertEmpty() tag("breakStatement.2")
+ }
+ }
+
+ private static void catchNotExecuted() {
+ try {
+ nop("try");
+ } catch (Exception e) { // tag("catchNotExecuted")
+ nop("catch"); // assertNotCovered()
+ } finally { // assertEmpty()
+ nop("finally"); // assertFullyCovered() tag("catchNotExecuted.1")
+ } // assertEmpty() tag("catchNotExecuted.2")
+ }
+
+ private static void emptyCatch() {
+ try {
+ nop("try");
+ } catch (Exception e) { // tag("emptyCatch")
+ /* empty */
+ } finally { // assertEmpty()
+ nop("finally"); // assertFullyCovered() tag("emptyCatch.1")
+ } // assertEmpty() tag("emptyCatch.2")
+ }
+
+ private static void twoRegions() {
+ try {
+ /* jump to another region associated with same handler: */
+ if (t()) { // assertFullyCovered(1, 1)
+ nop(); // assertFullyCovered()
+ return; // assertTwoRegionsReturn1()
+ } else {
+ nop(); // assertNotCovered()
+ return; // assertTwoRegionsReturn2()
+ }
+ } finally { // assertEmpty()
+ nop(); // assertTwoRegions1()
+ } // assertEmpty()
+ }
+
+ private static void nested() {
+ try {
+ nop();
+ } finally { // assertFinally() tag("nested.0")
+ try { // assertEmpty()
+ nop(); // assertFullyCovered()
+ } finally { // assertFinally() tag("nested.3")
+ nop(); // assertFullyCovered()
+ } // assertEmpty() tag("nested.5")
+ } // assertEmpty() tag("nested.6")
+ }
+
+ private static void emptyTry() {
+ try {
+ /* empty */
+ } finally { // assertEmpty()
+ nop(); // assertEmptyTry1()
+ } // assertEmptyTry2() tag("emptyTry.2")
+ }
+
+ @SuppressWarnings("finally")
+ private static void alwaysCompletesAbruptly() {
+ try {
+ nop();
+ } finally { // assertAlwaysCompletesAbruptly0()tag("alwaysCompletesAbruptly.0")
+ return; // assertAlwaysCompletesAbruptly1()
+ } // assertEmpty()
+ }
+
+ public static void main(String[] args) {
+ example(false);
+ try {
+ example(true);
+ } catch (Exception ignore) {
+ }
+
+ breakStatement();
+
+ catchNotExecuted();
+
+ emptyCatch();
+
+ twoRegions();
+
+ nested();
+
+ emptyTry();
+
+ alwaysCompletesAbruptly();
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/ImplicitFieldInitializationTarget.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/ImplicitFieldInitializationTarget.java
new file mode 100644
index 00000000..46433454
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/ImplicitFieldInitializationTarget.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.test.validation.java5.targets;
+
+/**
+ * This test target has instance members with implicit initializers.
+ */
+public class ImplicitFieldInitializationTarget { // assertFullyCovered()
+
+ Object field1; // assertEmpty()
+
+ Object field2 = this; // assertFullyCovered()
+
+ int field3; // assertEmpty()
+
+ int field4 = 2000; // assertFullyCovered()
+
+ public static void main(String[] args) {
+ new ImplicitFieldInitializationTarget();
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/InterfaceClassInitializerTarget.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/InterfaceClassInitializerTarget.java
new file mode 100644
index 00000000..81bcda82
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/InterfaceClassInitializerTarget.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.test.validation.java5.targets;
+
+import static org.jacoco.core.test.validation.targets.Stubs.i1;
+
+/**
+ * This test target is an interface with a class initializer.
+ */
+public interface InterfaceClassInitializerTarget {
+
+ /* No code required to initialize these fields: */
+
+ static final int CONST1 = 12345; // assertEmpty()
+
+ static final String CONST2 = "const"; // assertEmpty()
+
+ /* These fields are initialized within <clinit> */
+
+ static final int CONST3 = i1(); // assertFullyCovered()
+
+ static final Object CONST4 = new Object(); // assertFullyCovered()
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/StructuredLockingTarget.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/StructuredLockingTarget.java
new file mode 100644
index 00000000..76b57f93
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/StructuredLockingTarget.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.test.validation.java5.targets;
+
+import static org.jacoco.core.test.validation.targets.Stubs.nop;
+
+/**
+ * This target uses synchronized blocks which compile to try/catch statements.
+ */
+public class StructuredLockingTarget {
+
+ static void simple() {
+ Object lock1 = new Object();
+ synchronized (lock1) {
+ nop();
+ }
+ }
+
+ static void nested() {
+ Object lock1 = new Object();
+ synchronized (lock1) {
+ nop();
+ Object lock2 = new Object();
+ synchronized (lock2) {
+ nop();
+ }
+ nop();
+ }
+
+ }
+
+ public static void main(String[] args) {
+ simple();
+ nested();
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/SynchronizedTarget.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/SynchronizedTarget.java
new file mode 100644
index 00000000..b9b9ce66
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/SynchronizedTarget.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.java5.targets;
+
+import static org.jacoco.core.test.validation.targets.Stubs.ex;
+import static org.jacoco.core.test.validation.targets.Stubs.nop;
+
+import org.jacoco.core.test.validation.targets.Stubs.StubException;
+
+/**
+ * This test target is a synchronized statement.
+ */
+public class SynchronizedTarget {
+
+ private static final Object lock = new Object();
+
+ private static void normal() {
+ nop(); // assertFullyCovered()
+ /* when compiled with ECJ next line covered partly without filter: */
+ synchronized (lock) { // assertFullyCovered()
+ nop(); // assertFullyCovered()
+ } // assertMonitorExit()
+ nop(); // assertFullyCovered()
+ }
+
+ private static void explicitException() {
+ synchronized (lock) { // assertFullyCovered()
+ throw new StubException(); // assertFullyCovered()
+ } // assertEmpty()
+ }
+
+ private static void implicitException() {
+ synchronized (lock) { // assertMonitorEnterImplicitException()
+ ex(); // assertNotCovered()
+ } // assertMonitorExitImplicitException()
+ }
+
+ public static void main(String[] args) {
+ normal();
+
+ try {
+ explicitException();
+ } catch (StubException e) {
+ }
+
+ try {
+ implicitException();
+ } catch (StubException e) {
+ }
+ }
+
+}
diff --git a/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/SyntheticTarget.java b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/SyntheticTarget.java
new file mode 100644
index 00000000..efede92d
--- /dev/null
+++ b/org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/targets/SyntheticTarget.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2019 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.java5.targets;
+
+/**
+ * This test target results in synthetic methods.
+ */
+public class SyntheticTarget { // assertEmpty()
+
+ private static int counter; // assertEmpty()
+
+ /**
+ * {@link org.jacoco.core.test.validation.java5.targets.ConstructorsTarget
+ * Default constructor will refer to a line of class definition}, so that we
+ * define constructor explicitly in order to verify that we filter all other
+ * constructions here that might refer to line of class definition.
+ */
+ private SyntheticTarget() {
+ }
+
+ static class Inner extends SyntheticTarget { // assertEmpty()
+
+ Inner() {
+ }
+
+ /**
+ * Access to private field of outer class causes creation of synthetic
+ * methods in it. In case of javac those methods refer to the line of
+ * outer class definition, in case of ECJ - to the line of field.
+ */
+ private static void inc() {
+ counter = counter + 2;
+ }
+
+ /**
+ * Difference of return type with overridden method causes creation of
+ * synthetic bridge method in this class. In case of javac this method
+ * refers to the line of inner class definition, in case of EJC - to the
+ * first line of file.
+ */
+ @Override
+ public String get() {
+ return null;
+ }
+ }
+
+ public Object get() {
+ return null;
+ }
+
+ public static void main(String[] args) {
+ Inner.inc();
+ }
+
+}