Tests can detect that they were compiled by ECJ (#497)

diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/validation/Compiler.java b/org.jacoco.core.test/src/org/jacoco/core/test/validation/Compiler.java
new file mode 100644
index 0000000..c15ae1f
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/test/validation/Compiler.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2017 Mountainminds GmbH & Co. KG and Contributors
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Evgeny Mandrikov - initial API and implementation
+ *
+ *******************************************************************************/
+package org.jacoco.core.test.validation;
+
+/**
+ * Provides ability to detect compiler based on difference in generated bytecode
+ * for switch by enum.
+ */
+enum Compiler {
+
+	DETECT;
+
+	/**
+	 * @return <code>true</code> if this file was compiled by javac
+	 */
+	boolean isJDK() {
+		switch (DETECT) {
+		default:
+			try {
+				Compiler.class.getDeclaredField("$SWITCH_TABLE$"
+						+ Compiler.class.getName().replace('.', '$'));
+				return false;
+			} catch (NoSuchFieldException e) {
+				return true;
+			}
+		}
+	}
+
+}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/validation/ExceptionsTest.java b/org.jacoco.core.test/src/org/jacoco/core/test/validation/ExceptionsTest.java
index c1e4172..8fa8ee4 100644
--- a/org.jacoco.core.test/src/org/jacoco/core/test/validation/ExceptionsTest.java
+++ b/org.jacoco.core.test/src/org/jacoco/core/test/validation/ExceptionsTest.java
@@ -48,15 +48,11 @@
 		// 3. Try/Catch Block Without Exception Thrown
 		assertLine("noExceptionTryCatch.beforeBlock", ICounter.FULLY_COVERED);
 		assertLine("noExceptionTryCatch.tryBlock", ICounter.FULLY_COVERED);
-		if (isJDKCompiler()) {
-			assertLine("noExceptionTryCatch.catch",
-			/* partly when ECJ: */ICounter.NOT_COVERED);
-		}
+		assertLine("noExceptionTryCatch.catch",
+				isJDKCompiler ? ICounter.NOT_COVERED : ICounter.PARTLY_COVERED);
 		assertLine("noExceptionTryCatch.catchBlock", ICounter.NOT_COVERED);
-		if (isJDKCompiler()) {
-			assertLine("noExceptionTryCatch.catchBlockEnd",
-			/* empty when ECJ: */ICounter.FULLY_COVERED);
-		}
+		assertLine("noExceptionTryCatch.catchBlockEnd",
+				isJDKCompiler ? ICounter.FULLY_COVERED : ICounter.EMPTY);
 		assertLine("noExceptionTryCatch.afterBlock", ICounter.FULLY_COVERED);
 
 		// 4. Try/Catch Block With Exception Thrown Implicitly
@@ -65,16 +61,12 @@
 		assertLine("implicitExceptionTryCatch.before", ICounter.FULLY_COVERED);
 		assertLine("implicitExceptionTryCatch.exception", ICounter.NOT_COVERED);
 		assertLine("implicitExceptionTryCatch.after", ICounter.NOT_COVERED);
-		if (isJDKCompiler()) {
-			assertLine("implicitExceptionTryCatch.catch",
-			/* partly when ECJ: */ICounter.FULLY_COVERED);
-		}
+		assertLine("implicitExceptionTryCatch.catch", isJDKCompiler
+				? ICounter.FULLY_COVERED : ICounter.PARTLY_COVERED);
 		assertLine("implicitExceptionTryCatch.catchBlock",
 				ICounter.FULLY_COVERED);
-		if (isJDKCompiler()) {
-			assertLine("implicitExceptionTryCatch.catchBlockEnd",
-			/* empty when ECJ: */ICounter.NOT_COVERED);
-		}
+		assertLine("implicitExceptionTryCatch.catchBlockEnd",
+				isJDKCompiler ? ICounter.NOT_COVERED : ICounter.EMPTY);
 		assertLine("implicitExceptionTryCatch.afterBlock",
 				ICounter.FULLY_COVERED);
 
@@ -104,15 +96,11 @@
 		// Finally block is yellow as the exception path is missing.
 		assertLine("noExceptionFinally.beforeBlock", ICounter.FULLY_COVERED);
 		assertLine("noExceptionFinally.tryBlock", ICounter.FULLY_COVERED);
-		if (isJDKCompiler()) {
-			assertLine("noExceptionFinally.finally",
-			/* partly when ECJ: */ICounter.EMPTY);
-		}
+		assertLine("noExceptionFinally.finally",
+				isJDKCompiler ? ICounter.EMPTY : ICounter.PARTLY_COVERED);
 		assertLine("noExceptionFinally.finallyBlock", ICounter.PARTLY_COVERED);
-		if (isJDKCompiler()) {
-			assertLine("noExceptionFinally.finallyBlockEnd",
-			/* not covered when ECJ: */ICounter.FULLY_COVERED);
-		}
+		assertLine("noExceptionFinally.finallyBlockEnd",
+				isJDKCompiler ? ICounter.FULLY_COVERED : ICounter.NOT_COVERED);
 		assertLine("noExceptionFinally.afterBlock", ICounter.FULLY_COVERED);
 
 		// 8. Finally Block With Implicit Exception
@@ -122,16 +110,12 @@
 		assertLine("implicitExceptionFinally.before", ICounter.FULLY_COVERED);
 		assertLine("implicitExceptionFinally.exception", ICounter.NOT_COVERED);
 		assertLine("implicitExceptionFinally.after", ICounter.NOT_COVERED);
-		if (isJDKCompiler()) {
-			assertLine("implicitExceptionFinally.finally",
-			/* partly when ECJ: */ICounter.EMPTY);
-		}
+		assertLine("implicitExceptionFinally.finally",
+				isJDKCompiler ? ICounter.EMPTY : ICounter.PARTLY_COVERED);
 		assertLine("implicitExceptionFinally.finallyBlock",
 				ICounter.PARTLY_COVERED);
-		if (isJDKCompiler()) {
-			assertLine("implicitExceptionFinally.finallyBlockEnd",
-			/* fully when ECJ: */ICounter.NOT_COVERED);
-		}
+		assertLine("implicitExceptionFinally.finallyBlockEnd",
+				isJDKCompiler ? ICounter.NOT_COVERED : ICounter.FULLY_COVERED);
 		assertLine("implicitExceptionFinally.afterBlock", ICounter.NOT_COVERED);
 
 		// 9. Finally Block With Exception Thrown Explicitly
@@ -139,16 +123,12 @@
 				ICounter.FULLY_COVERED);
 		assertLine("explicitExceptionFinally.before", ICounter.FULLY_COVERED);
 		assertLine("explicitExceptionFinally.throw", ICounter.FULLY_COVERED);
-		if (isJDKCompiler()) {
-			assertLine("explicitExceptionFinally.finally",
-			/* fully when ECJ: */ICounter.EMPTY);
-		}
+		assertLine("explicitExceptionFinally.finally",
+				isJDKCompiler ? ICounter.EMPTY : ICounter.FULLY_COVERED);
 		assertLine("explicitExceptionFinally.finallyBlock",
 				ICounter.FULLY_COVERED);
-		if (isJDKCompiler()) {
-			assertLine("explicitExceptionFinally.finallyBlockEnd",
-			/* fully when ECJ: */ICounter.EMPTY);
-		}
+		assertLine("explicitExceptionFinally.finallyBlockEnd",
+				isJDKCompiler ? ICounter.EMPTY : ICounter.FULLY_COVERED);
 		assertLine("explicitExceptionFinally.afterBlock", ICounter.EMPTY);
 
 	}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/test/validation/ValidationTestBase.java b/org.jacoco.core.test/src/org/jacoco/core/test/validation/ValidationTestBase.java
index c943e3e..8521d96 100644
--- a/org.jacoco.core.test/src/org/jacoco/core/test/validation/ValidationTestBase.java
+++ b/org.jacoco.core.test/src/org/jacoco/core/test/validation/ValidationTestBase.java
@@ -37,6 +37,8 @@
  */
 public abstract class ValidationTestBase {
 
+	static final boolean isJDKCompiler = Compiler.DETECT.isJDK();
+
 	private static final String[] STATUS_NAME = new String[4];
 
 	{
@@ -107,10 +109,6 @@
 		analyzer.analyzeClass(bytes, data.getName());
 	}
 
-	boolean isJDKCompiler() {
-		return System.getProperty("bytecode.version") != null;
-	}
-
 	protected void assertLine(final String tag, final int status) {
 		final int nr = source.getLineNumber(tag);
 		final ILine line = sourceCoverage.getLine(nr);