149 lines
6.1 KiB
Diff
149 lines
6.1 KiB
Diff
// SPDX-License-Identifier: EPL-2.0 and Apache-2.0
|
|
// These patches apply to JaCoCo (https://github.com/jacoco/jacoco) and are hereby made available under the terms of the
|
|
// Eclipse Public License 2.0 available at:
|
|
// http://www.eclipse.org/legal/epl-2.0
|
|
diff --git org.jacoco.core/src/org/jacoco/core/internal/instr/ClassInstrumenter.java org.jacoco.core/src/org/jacoco/core/internal/instr/ClassInstrumenter.java
|
|
index 476c9e34..bc192dc6 100644
|
|
--- org.jacoco.core/src/org/jacoco/core/internal/instr/ClassInstrumenter.java
|
|
+++ org.jacoco.core/src/org/jacoco/core/internal/instr/ClassInstrumenter.java
|
|
@@ -24,6 +24,7 @@ import org.objectweb.asm.MethodVisitor;
|
|
public class ClassInstrumenter extends ClassProbesVisitor {
|
|
|
|
private final IProbeArrayStrategy probeArrayStrategy;
|
|
+ private final IProbeInserterFactory probeInserterFactory;
|
|
|
|
private String className;
|
|
|
|
@@ -40,6 +41,22 @@ public class ClassInstrumenter extends ClassProbesVisitor {
|
|
final ClassVisitor cv) {
|
|
super(cv);
|
|
this.probeArrayStrategy = probeArrayStrategy;
|
|
+ this.probeInserterFactory = new IProbeInserterFactory() {
|
|
+ @Override
|
|
+ public ProbeInserter makeProbeInserter(int access, String name,
|
|
+ String desc, MethodVisitor mv,
|
|
+ IProbeArrayStrategy arrayStrategy) {
|
|
+ return new ProbeInserter(access, name, desc, mv, arrayStrategy);
|
|
+ }
|
|
+ };
|
|
+ }
|
|
+
|
|
+ public ClassInstrumenter(final IProbeArrayStrategy probeArrayStrategy,
|
|
+ final IProbeInserterFactory probeInserterFactory,
|
|
+ final ClassVisitor cv) {
|
|
+ super(cv);
|
|
+ this.probeArrayStrategy = probeArrayStrategy;
|
|
+ this.probeInserterFactory = probeInserterFactory;
|
|
}
|
|
|
|
@Override
|
|
@@ -71,8 +88,9 @@ public class ClassInstrumenter extends ClassProbesVisitor {
|
|
return null;
|
|
}
|
|
final MethodVisitor frameEliminator = new DuplicateFrameEliminator(mv);
|
|
- final ProbeInserter probeVariableInserter = new ProbeInserter(access,
|
|
- name, desc, frameEliminator, probeArrayStrategy);
|
|
+ final ProbeInserter probeVariableInserter =
|
|
+ probeInserterFactory.makeProbeInserter(access, name, desc,
|
|
+ frameEliminator, probeArrayStrategy);
|
|
return new MethodInstrumenter(probeVariableInserter,
|
|
probeVariableInserter);
|
|
}
|
|
diff --git org.jacoco.core/src/org/jacoco/core/internal/instr/IProbeInserterFactory.java org.jacoco.core/src/org/jacoco/core/internal/instr/IProbeInserterFactory.java
|
|
new file mode 100644
|
|
index 00000000..19c2a7e2
|
|
--- /dev/null
|
|
+++ org.jacoco.core/src/org/jacoco/core/internal/instr/IProbeInserterFactory.java
|
|
@@ -0,0 +1,8 @@
|
|
+package org.jacoco.core.internal.instr;
|
|
+
|
|
+import org.objectweb.asm.MethodVisitor;
|
|
+
|
|
+public interface IProbeInserterFactory {
|
|
+ ProbeInserter makeProbeInserter(int access, String name, String desc,
|
|
+ MethodVisitor mv, IProbeArrayStrategy arrayStrategy);
|
|
+}
|
|
diff --git org.jacoco.core/src/org/jacoco/core/internal/instr/ProbeInserter.java org.jacoco.core/src/org/jacoco/core/internal/instr/ProbeInserter.java
|
|
index 0f5b99ff..80965dfe 100644
|
|
--- org.jacoco.core/src/org/jacoco/core/internal/instr/ProbeInserter.java
|
|
+++ org.jacoco.core/src/org/jacoco/core/internal/instr/ProbeInserter.java
|
|
@@ -25,7 +25,7 @@ import org.objectweb.asm.TypePath;
|
|
* addition the probe array has to be retrieved at the beginning of the method
|
|
* and stored in a local variable.
|
|
*/
|
|
-class ProbeInserter extends MethodVisitor implements IProbeInserter {
|
|
+public class ProbeInserter extends MethodVisitor implements IProbeInserter {
|
|
|
|
private final IProbeArrayStrategy arrayStrategy;
|
|
|
|
@@ -36,7 +36,7 @@ class ProbeInserter extends MethodVisitor implements IProbeInserter {
|
|
private final boolean clinit;
|
|
|
|
/** Position of the inserted variable. */
|
|
- private final int variable;
|
|
+ protected final int variable;
|
|
|
|
/** Label for the new beginning of the method */
|
|
private final Label beginLabel;
|
|
@@ -56,7 +56,7 @@ class ProbeInserter extends MethodVisitor implements IProbeInserter {
|
|
* callback to create the code that retrieves the reference to
|
|
* the probe array
|
|
*/
|
|
- ProbeInserter(final int access, final String name, final String desc,
|
|
+ public ProbeInserter(final int access, final String name, final String desc,
|
|
final MethodVisitor mv, final IProbeArrayStrategy arrayStrategy) {
|
|
super(InstrSupport.ASM_API_VERSION, mv);
|
|
this.clinit = InstrSupport.CLINIT_NAME.equals(name);
|
|
@@ -91,6 +91,10 @@ class ProbeInserter extends MethodVisitor implements IProbeInserter {
|
|
mv.visitInsn(Opcodes.BASTORE);
|
|
}
|
|
|
|
+ protected Object getLocalVariableType() {
|
|
+ return InstrSupport.DATAFIELD_DESC;
|
|
+ }
|
|
+
|
|
@Override
|
|
public void visitCode() {
|
|
mv.visitLabel(beginLabel);
|
|
@@ -118,6 +122,10 @@ class ProbeInserter extends MethodVisitor implements IProbeInserter {
|
|
public AnnotationVisitor visitLocalVariableAnnotation(final int typeRef,
|
|
final TypePath typePath, final Label[] start, final Label[] end,
|
|
final int[] index, final String descriptor, final boolean visible) {
|
|
+ if (getLocalVariableType() == null) {
|
|
+ return mv.visitLocalVariableAnnotation(typeRef, typePath, start, end, index, descriptor, visible);
|
|
+ }
|
|
+
|
|
final int[] newIndex = new int[index.length];
|
|
for (int i = 0; i < newIndex.length; i++) {
|
|
newIndex[i] = map(index[i]);
|
|
@@ -137,6 +145,9 @@ class ProbeInserter extends MethodVisitor implements IProbeInserter {
|
|
}
|
|
|
|
private int map(final int var) {
|
|
+ if (getLocalVariableType() == null) {
|
|
+ return var;
|
|
+ }
|
|
if (var < variable) {
|
|
return var;
|
|
} else {
|
|
@@ -153,13 +164,18 @@ class ProbeInserter extends MethodVisitor implements IProbeInserter {
|
|
"ClassReader.accept() should be called with EXPAND_FRAMES flag");
|
|
}
|
|
|
|
+ if (getLocalVariableType() == null) {
|
|
+ mv.visitFrame(type, nLocal, local, nStack, stack);
|
|
+ return;
|
|
+ }
|
|
+
|
|
final Object[] newLocal = new Object[Math.max(nLocal, variable) + 1];
|
|
int idx = 0; // Arrays index for existing locals
|
|
int newIdx = 0; // Array index for new locals
|
|
int pos = 0; // Current variable position
|
|
while (idx < nLocal || pos <= variable) {
|
|
if (pos == variable) {
|
|
- newLocal[newIdx++] = InstrSupport.DATAFIELD_DESC;
|
|
+ newLocal[newIdx++] = getLocalVariableType();
|
|
pos++;
|
|
} else {
|
|
if (idx < nLocal) {
|