aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvgeny Mandrikov <138671+Godin@users.noreply.github.com>2019-01-22 23:23:48 +0100
committerMarc R. Hoffmann <hoffmann@mountainminds.com>2019-01-22 23:23:48 +0100
commit2034d40ee2172339f33229f057d15b2b4e7aae29 (patch)
tree53df4f9b9b2b38ec208abfe7a59c3c3a1631357d
parentb7441f2b51b3d147554845710c809e5a562dc36f (diff)
downloadplatform_external_jacoco-2034d40ee2172339f33229f057d15b2b4e7aae29.tar.gz
platform_external_jacoco-2034d40ee2172339f33229f057d15b2b4e7aae29.tar.bz2
platform_external_jacoco-2034d40ee2172339f33229f057d15b2b4e7aae29.zip
Add experimental support for Java 13 class files (#835)
-rw-r--r--org.jacoco.ant.test/src/org/jacoco/ant/RemoveDebugInfos.java5
-rw-r--r--org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/InstrumentTest.java5
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/FinallyTest.java4
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/FramesTest.java2
-rw-r--r--org.jacoco.core.test.validation.java5/src/org/jacoco/core/test/validation/java5/StructuredLockingTest.java4
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/analysis/AnalyzerTest.java2
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/instr/ClassFileVersionsTest.java8
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/instr/InstrumenterTest.java2
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/instr/ResizeInstructionsTest.java2
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/internal/ContentTypeDetectorTest.java14
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/internal/instr/InstrSupportTest.java31
-rw-r--r--org.jacoco.core/src/org/jacoco/core/analysis/Analyzer.java3
-rw-r--r--org.jacoco.core/src/org/jacoco/core/instr/Instrumenter.java2
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/ContentTypeDetector.java2
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/instr/InstrSupport.java22
-rw-r--r--org.jacoco.core/src/org/jacoco/core/runtime/ModifiedSystemClassRuntime.java2
-rw-r--r--org.jacoco.doc/docroot/doc/changes.html2
17 files changed, 96 insertions, 16 deletions
diff --git a/org.jacoco.ant.test/src/org/jacoco/ant/RemoveDebugInfos.java b/org.jacoco.ant.test/src/org/jacoco/ant/RemoveDebugInfos.java
index e82b8d58..7f9eb8d7 100644
--- a/org.jacoco.ant.test/src/org/jacoco/ant/RemoveDebugInfos.java
+++ b/org.jacoco.ant.test/src/org/jacoco/ant/RemoveDebugInfos.java
@@ -16,6 +16,8 @@ import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
+import org.jacoco.core.internal.InputStreams;
+import org.jacoco.core.internal.instr.InstrSupport;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
@@ -26,7 +28,8 @@ public class RemoveDebugInfos {
public static void main(String[] args) throws Exception {
final InputStream in = new FileInputStream(args[0]);
- final ClassReader reader = new ClassReader(in);
+ final ClassReader reader = InstrSupport
+ .classReaderFor(InputStreams.readFully(in));
in.close();
final ClassWriter writer = new ClassWriter(0);
diff --git a/org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/InstrumentTest.java b/org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/InstrumentTest.java
index 556c09e8..ff49aa8d 100644
--- a/org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/InstrumentTest.java
+++ b/org.jacoco.cli.test/src/org/jacoco/cli/internal/commands/InstrumentTest.java
@@ -26,6 +26,7 @@ import java.util.HashSet;
import java.util.Set;
import org.jacoco.cli.internal.CommandTestBase;
+import org.jacoco.core.internal.InputStreams;
import org.jacoco.core.internal.instr.InstrSupport;
import org.junit.Rule;
import org.junit.Test;
@@ -33,7 +34,6 @@ import org.junit.rules.TemporaryFolder;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
-import org.objectweb.asm.Opcodes;
/**
* Unit tests for {@link Instrument}.
@@ -135,7 +135,8 @@ public class InstrumentTest extends CommandTestBase {
private void assertInstrumented(File classfile) throws IOException {
InputStream in = new FileInputStream(classfile);
- ClassReader reader = new ClassReader(in);
+ final ClassReader reader = InstrSupport
+ .classReaderFor(InputStreams.readFully(in));
in.close();
final Set<String> fields = new HashSet<String>();
reader.accept(new ClassVisitor(InstrSupport.ASM_API_VERSION) {
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
index 54276cdc..91a81247 100644
--- 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
@@ -21,13 +21,13 @@ 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.ClassReader;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
@@ -195,7 +195,7 @@ public class FinallyTest extends ValidationTestBase {
byte[] b = TargetLoader.getClassDataAsBytes(FinallyTarget.class);
final ClassNode classNode = new ClassNode();
- new ClassReader(b).accept(classNode, 0);
+ InstrSupport.classReaderFor(b).accept(classNode, 0);
for (final MethodNode m : classNode.methods) {
if ("main".equals(m.name)) {
// skip it
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
index 92ac9074..88e39039 100644
--- 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
@@ -86,7 +86,7 @@ public class FramesTest {
}
private byte[] calculateFrames(byte[] source) {
- ClassReader rc = new ClassReader(source);
+ ClassReader rc = InstrSupport.classReaderFor(source);
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
// Adjust Version to 1.6 to enable frames:
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
index 1379616b..7e13e651 100644
--- 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
@@ -20,12 +20,12 @@ 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.ClassReader;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
@@ -65,7 +65,7 @@ public class StructuredLockingTest {
byte[] instrumented = instrumenter.instrument(source, "TestTarget");
ClassNode cn = new ClassNode();
- new ClassReader(instrumented).accept(cn, 0);
+ InstrSupport.classReaderFor(instrumented).accept(cn, 0);
for (MethodNode mn : cn.methods) {
assertStructuredLocking(cn.name, mn);
}
diff --git a/org.jacoco.core.test/src/org/jacoco/core/analysis/AnalyzerTest.java b/org.jacoco.core.test/src/org/jacoco/core/analysis/AnalyzerTest.java
index ffa48988..6f8fee9c 100644
--- a/org.jacoco.core.test/src/org/jacoco/core/analysis/AnalyzerTest.java
+++ b/org.jacoco.core.test/src/org/jacoco/core/analysis/AnalyzerTest.java
@@ -92,7 +92,7 @@ public class AnalyzerTest {
@Test
public void should_not_modify_class_bytes_to_support_next_version()
throws Exception {
- final byte[] originalBytes = createClass(Opcodes.V12);
+ final byte[] originalBytes = createClass(Opcodes.V12 + 1);
final byte[] bytes = new byte[originalBytes.length];
System.arraycopy(originalBytes, 0, bytes, 0, originalBytes.length);
final long expectedClassId = CRC64.classId(bytes);
diff --git a/org.jacoco.core.test/src/org/jacoco/core/instr/ClassFileVersionsTest.java b/org.jacoco.core.test/src/org/jacoco/core/instr/ClassFileVersionsTest.java
index 769b9eab..f1f8d16c 100644
--- a/org.jacoco.core.test/src/org/jacoco/core/instr/ClassFileVersionsTest.java
+++ b/org.jacoco.core.test/src/org/jacoco/core/instr/ClassFileVersionsTest.java
@@ -41,7 +41,6 @@ import org.jacoco.core.internal.instr.InstrSupport;
import org.jacoco.core.runtime.IRuntime;
import org.jacoco.core.runtime.SystemPropertiesRuntime;
import org.junit.Test;
-import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
@@ -113,6 +112,11 @@ public class ClassFileVersionsTest {
testVersion(V12, true);
}
+ @Test
+ public void test_13() throws IOException {
+ testVersion(V12 + 1, true);
+ }
+
private void testVersion(int version, boolean frames) throws IOException {
final byte[] original = createClass(version, frames);
@@ -124,7 +128,7 @@ public class ClassFileVersionsTest {
}
private void assertFrames(byte[] source, final boolean expected) {
- new ClassReader(source)
+ InstrSupport.classReaderFor(source)
.accept(new ClassVisitor(InstrSupport.ASM_API_VERSION) {
@Override
diff --git a/org.jacoco.core.test/src/org/jacoco/core/instr/InstrumenterTest.java b/org.jacoco.core.test/src/org/jacoco/core/instr/InstrumenterTest.java
index 406c5e80..d5104bcc 100644
--- a/org.jacoco.core.test/src/org/jacoco/core/instr/InstrumenterTest.java
+++ b/org.jacoco.core.test/src/org/jacoco/core/instr/InstrumenterTest.java
@@ -98,7 +98,7 @@ public class InstrumenterTest {
@Test
public void should_not_modify_class_bytes_to_support_next_version()
throws Exception {
- final byte[] originalBytes = createClass(Opcodes.V12);
+ final byte[] originalBytes = createClass(Opcodes.V12 + 1);
final byte[] bytes = new byte[originalBytes.length];
System.arraycopy(originalBytes, 0, bytes, 0, originalBytes.length);
final long expectedClassId = CRC64.classId(bytes);
diff --git a/org.jacoco.core.test/src/org/jacoco/core/instr/ResizeInstructionsTest.java b/org.jacoco.core.test/src/org/jacoco/core/instr/ResizeInstructionsTest.java
index bb671b13..1a8137cb 100644
--- a/org.jacoco.core.test/src/org/jacoco/core/instr/ResizeInstructionsTest.java
+++ b/org.jacoco.core.test/src/org/jacoco/core/instr/ResizeInstructionsTest.java
@@ -61,7 +61,7 @@ public class ResizeInstructionsTest {
public void should_not_loose_InnerClasses_attribute() throws Exception {
byte[] source = TargetLoader.getClassDataAsBytes(Inner.class);
- final ClassReader cr = new ClassReader(source);
+ final ClassReader cr = InstrSupport.classReaderFor(source);
final ClassWriter cw = new ClassWriter(0);
cr.accept(new ClassVisitor(InstrSupport.ASM_API_VERSION, cw) {
@Override
diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/ContentTypeDetectorTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/ContentTypeDetectorTest.java
index 6a1b08d3..a631b52e 100644
--- a/org.jacoco.core.test/src/org/jacoco/core/internal/ContentTypeDetectorTest.java
+++ b/org.jacoco.core.test/src/org/jacoco/core/internal/ContentTypeDetectorTest.java
@@ -152,6 +152,20 @@ public class ContentTypeDetectorTest {
}
@Test
+ public void should_detect_java_13() throws IOException {
+ initData(0xCA, 0xFE, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x39);
+ assertEquals(ContentTypeDetector.CLASSFILE, detector.getType());
+ assertContent();
+ }
+
+ @Test
+ public void should_detect_java_13_with_preview_features() throws IOException {
+ initData(0xCA, 0xFE, 0xBA, 0xBE, 0xFF, 0xFF, 0x00, 0x39);
+ assertEquals(ContentTypeDetector.CLASSFILE, detector.getType());
+ assertContent();
+ }
+
+ @Test
public void testMachObjectFile() throws IOException {
initData(0xCA, 0xFE, 0xBA, 0xBE, 0x00, 0x00, 0x00, 0x02);
assertEquals(ContentTypeDetector.UNKNOWN, detector.getType());
diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/instr/InstrSupportTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/instr/InstrSupportTest.java
index eedea379..caec564b 100644
--- a/org.jacoco.core.test/src/org/jacoco/core/internal/instr/InstrSupportTest.java
+++ b/org.jacoco.core.test/src/org/jacoco/core/internal/instr/InstrSupportTest.java
@@ -11,6 +11,7 @@
*******************************************************************************/
package org.jacoco.core.internal.instr;
+import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -19,6 +20,9 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.util.Printer;
import org.objectweb.asm.util.Textifier;
@@ -42,6 +46,32 @@ public class InstrSupportTest {
}
@Test
+ public void classReaderFor_should_read_java_13_class() {
+ final byte[] bytes = createJava13Class();
+
+ final ClassReader classReader = InstrSupport.classReaderFor(bytes);
+
+ classReader.accept(new ClassVisitor(InstrSupport.ASM_API_VERSION) {
+ @Override
+ public void visit(final int version, final int access,
+ final String name, final String signature,
+ final String superName, final String[] interfaces) {
+ assertEquals(Opcodes.V12 + 1, version);
+ }
+ }, 0);
+
+ assertArrayEquals(createJava13Class(), bytes);
+ }
+
+ private static byte[] createJava13Class() {
+ final ClassWriter cw = new ClassWriter(0);
+ cw.visit(Opcodes.V12 + 1, 0, "Foo", null, "java/lang/Object", null);
+ cw.visitEnd();
+ cw.toByteArray();
+ return cw.toByteArray();
+ }
+
+ @Test
public void getVersionMajor_should_return_major_version_number() {
final byte[] bytes = new byte[] { (byte) 0xCA, (byte) 0xFE, (byte) 0xBA,
(byte) 0xBE, /* minor */ 0x00, 0x03, /* major */ 0x00, 0x2D };
@@ -66,6 +96,7 @@ public class InstrSupportTest {
assertTrue(InstrSupport.needsFrames(Opcodes.V10));
assertTrue(InstrSupport.needsFrames(Opcodes.V11));
assertTrue(InstrSupport.needsFrames(Opcodes.V12));
+ assertTrue(InstrSupport.needsFrames(Opcodes.V12 + 1));
}
@Test
diff --git a/org.jacoco.core/src/org/jacoco/core/analysis/Analyzer.java b/org.jacoco.core/src/org/jacoco/core/analysis/Analyzer.java
index 8b927459..97aa44f1 100644
--- a/org.jacoco.core/src/org/jacoco/core/analysis/Analyzer.java
+++ b/org.jacoco.core/src/org/jacoco/core/analysis/Analyzer.java
@@ -30,6 +30,7 @@ import org.jacoco.core.internal.analysis.ClassCoverageImpl;
import org.jacoco.core.internal.analysis.StringPool;
import org.jacoco.core.internal.data.CRC64;
import org.jacoco.core.internal.flow.ClassProbesAdapter;
+import org.jacoco.core.internal.instr.InstrSupport;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Opcodes;
@@ -112,7 +113,7 @@ public class Analyzer {
private void analyzeClass(final byte[] source) {
final long classId = CRC64.classId(source);
- final ClassReader reader = new ClassReader(source);
+ final ClassReader reader = InstrSupport.classReaderFor(source);
if ((reader.getAccess() & Opcodes.ACC_SYNTHETIC) != 0) {
return;
}
diff --git a/org.jacoco.core/src/org/jacoco/core/instr/Instrumenter.java b/org.jacoco.core/src/org/jacoco/core/instr/Instrumenter.java
index 201d75ee..89f14019 100644
--- a/org.jacoco.core/src/org/jacoco/core/instr/Instrumenter.java
+++ b/org.jacoco.core/src/org/jacoco/core/instr/Instrumenter.java
@@ -83,7 +83,7 @@ public class Instrumenter {
private byte[] instrument(final byte[] source) {
final long classId = CRC64.classId(source);
- final ClassReader reader = new ClassReader(source);
+ final ClassReader reader = InstrSupport.classReaderFor(source);
final ClassWriter writer = new ClassWriter(reader, 0) {
@Override
protected String getCommonSuperClass(final String type1,
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/ContentTypeDetector.java b/org.jacoco.core/src/org/jacoco/core/internal/ContentTypeDetector.java
index 1d7617ee..74574ecc 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/ContentTypeDetector.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/ContentTypeDetector.java
@@ -88,6 +88,8 @@ public class ContentTypeDetector {
case Opcodes.V11 | Opcodes.V_PREVIEW:
case Opcodes.V12:
case Opcodes.V12 | Opcodes.V_PREVIEW:
+ case (Opcodes.V12 + 1):
+ case (Opcodes.V12 + 1) | Opcodes.V_PREVIEW:
return CLASSFILE;
}
}
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/instr/InstrSupport.java b/org.jacoco.core/src/org/jacoco/core/internal/instr/InstrSupport.java
index ce4bcbee..99e00270 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/instr/InstrSupport.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/instr/InstrSupport.java
@@ -13,6 +13,7 @@ package org.jacoco.core.internal.instr;
import static java.lang.String.format;
+import org.objectweb.asm.ClassReader;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
@@ -227,4 +228,25 @@ public final class InstrSupport {
}
}
+ /**
+ * Creates a {@link ClassReader} instance for given bytes of class even if
+ * its version not yet supported by ASM.
+ *
+ * @param b
+ * bytes of class
+ * @return {@link ClassReader}
+ */
+ public static ClassReader classReaderFor(final byte[] b) {
+ final byte[] originalVersion = new byte[] { b[4], b[5], b[6], b[7] };
+ if (getVersionMajor(b) == Opcodes.V12 + 1) {
+ b[4] = (byte) (Opcodes.V12 >>> 24);
+ b[5] = (byte) (Opcodes.V12 >>> 16);
+ b[6] = (byte) (Opcodes.V12 >>> 8);
+ b[7] = (byte) Opcodes.V12;
+ }
+ final ClassReader classReader = new ClassReader(b);
+ System.arraycopy(originalVersion, 0, b, 4, originalVersion.length);
+ return classReader;
+ }
+
}
diff --git a/org.jacoco.core/src/org/jacoco/core/runtime/ModifiedSystemClassRuntime.java b/org.jacoco.core/src/org/jacoco/core/runtime/ModifiedSystemClassRuntime.java
index a18f7299..5f2cc497 100644
--- a/org.jacoco.core/src/org/jacoco/core/runtime/ModifiedSystemClassRuntime.java
+++ b/org.jacoco.core/src/org/jacoco/core/runtime/ModifiedSystemClassRuntime.java
@@ -153,7 +153,7 @@ public class ModifiedSystemClassRuntime extends AbstractRuntime {
*/
public static byte[] instrument(final byte[] source,
final String accessFieldName) {
- final ClassReader reader = new ClassReader(source);
+ final ClassReader reader = InstrSupport.classReaderFor(source);
final ClassWriter writer = new ClassWriter(reader, 0);
reader.accept(new ClassVisitor(InstrSupport.ASM_API_VERSION, writer) {
diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html
index e673eb5f..1cfeb212 100644
--- a/org.jacoco.doc/docroot/doc/changes.html
+++ b/org.jacoco.doc/docroot/doc/changes.html
@@ -26,6 +26,8 @@
(GitHub <a href="https://github.com/jacoco/jacoco/issues/821">#821</a>).</li>
<li>JaCoCo now officially supports Java 11
(GitHub <a href="https://github.com/jacoco/jacoco/issues/760">#760</a>).</li>
+ <li>Experimental support for Java 13 class files
+ (GitHub <a href="https://github.com/jacoco/jacoco/issues/835">#835</a>).</li>
<li>Branch added by the Kotlin compiler for "unsafe" cast operator is filtered
out during generation of report
(GitHub <a href="https://github.com/jacoco/jacoco/issues/761">#761</a>).</li>