aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassAnalyzerTest.java47
-rw-r--r--org.jacoco.core.test/src/org/jacoco/core/internal/instr/InstrSupportTest.java15
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassAnalyzer.java11
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/instr/ClassInstrumenter.java27
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/instr/InstrSupport.java23
-rw-r--r--org.jacoco.doc/docroot/doc/changes.html2
6 files changed, 100 insertions, 25 deletions
diff --git a/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassAnalyzerTest.java b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassAnalyzerTest.java
new file mode 100644
index 00000000..c60901c2
--- /dev/null
+++ b/org.jacoco.core.test/src/org/jacoco/core/internal/analysis/ClassAnalyzerTest.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2013 Mountainminds GmbH & Co. KG and Contributors
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ *******************************************************************************/
+package org.jacoco.core.internal.analysis;
+
+import org.jacoco.core.internal.instr.InstrSupport;
+import org.junit.Before;
+import org.junit.Test;
+import org.objectweb.asm.Opcodes;
+
+/**
+ * Unit tests for {@link ClassAnalyzer}.
+ */
+public class ClassAnalyzerTest {
+
+ private ClassAnalyzer analyzer;
+
+ @Before
+ public void setup() {
+ analyzer = new ClassAnalyzer(0x0000, null, new StringPool());
+ analyzer.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "Foo", null,
+ "java/lang/Object", null);
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testAnalyzeInstrumentedClass1() {
+ analyzer.visitField(InstrSupport.DATAFIELD_ACC,
+ InstrSupport.DATAFIELD_NAME, InstrSupport.DATAFIELD_DESC, null,
+ null);
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testAnalyzeInstrumentedClass2() {
+ analyzer.visitMethod(InstrSupport.INITMETHOD_ACC,
+ InstrSupport.INITMETHOD_NAME, InstrSupport.INITMETHOD_DESC,
+ null, null);
+ }
+
+}
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 f10fe6fb..1d8004a4 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
@@ -34,6 +34,21 @@ public class InstrSupportTest {
}
@Test
+ public void testAssertNotIntrumentedPositive() {
+ InstrSupport.assertNotInstrumented("run", "Foo");
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testAssertNotIntrumentedField() {
+ InstrSupport.assertNotInstrumented("$jacocoData", "Foo");
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testAssertNotIntrumentedMethod() {
+ InstrSupport.assertNotInstrumented("$jacocoInit", "Foo");
+ }
+
+ @Test
public void testPushIntM2147483648() {
InstrSupport.push(trace, -2147483648);
assertInstruction("LDC -2147483648");
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassAnalyzer.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassAnalyzer.java
index ee8f05a2..9fa52889 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassAnalyzer.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/ClassAnalyzer.java
@@ -14,6 +14,8 @@ package org.jacoco.core.internal.analysis;
import org.jacoco.core.analysis.IMethodCoverage;
import org.jacoco.core.internal.flow.ClassProbesVisitor;
import org.jacoco.core.internal.flow.MethodProbesVisitor;
+import org.jacoco.core.internal.instr.InstrSupport;
+import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Opcodes;
/**
@@ -72,6 +74,8 @@ public class ClassAnalyzer extends ClassProbesVisitor {
public MethodProbesVisitor visitMethod(final int access, final String name,
final String desc, final String signature, final String[] exceptions) {
+ InstrSupport.assertNotInstrumented(name, coverage.getName());
+
// TODO: Use filter hook
if ((access & Opcodes.ACC_SYNTHETIC) != 0) {
return null;
@@ -92,6 +96,13 @@ public class ClassAnalyzer extends ClassProbesVisitor {
}
@Override
+ public FieldVisitor visitField(final int access, final String name,
+ final String desc, final String signature, final Object value) {
+ InstrSupport.assertNotInstrumented(name, coverage.getName());
+ return super.visitField(access, name, desc, signature, value);
+ }
+
+ @Override
public void visitTotalProbeCount(final int count) {
// nothing to do
}
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/instr/ClassInstrumenter.java b/org.jacoco.core/src/org/jacoco/core/internal/instr/ClassInstrumenter.java
index 796a004a..d9fb76ea 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/instr/ClassInstrumenter.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/instr/ClassInstrumenter.java
@@ -11,8 +11,6 @@
*******************************************************************************/
package org.jacoco.core.internal.instr;
-import static java.lang.String.format;
-
import org.jacoco.core.internal.flow.ClassProbesVisitor;
import org.jacoco.core.internal.flow.MethodProbesVisitor;
import org.jacoco.core.runtime.IExecutionDataAccessorGenerator;
@@ -78,7 +76,7 @@ public class ClassInstrumenter extends ClassProbesVisitor {
@Override
public FieldVisitor visitField(final int access, final String name,
final String desc, final String signature, final Object value) {
- assertNotInstrumented(name, InstrSupport.DATAFIELD_NAME);
+ InstrSupport.assertNotInstrumented(name, className);
return super.visitField(access, name, desc, signature, value);
}
@@ -86,7 +84,7 @@ public class ClassInstrumenter extends ClassProbesVisitor {
public MethodProbesVisitor visitMethod(final int access, final String name,
final String desc, final String signature, final String[] exceptions) {
- assertNotInstrumented(name, InstrSupport.INITMETHOD_NAME);
+ InstrSupport.assertNotInstrumented(name, className);
final MethodVisitor mv = cv.visitMethod(access, name, desc, signature,
exceptions);
@@ -119,27 +117,6 @@ public class ClassInstrumenter extends ClassProbesVisitor {
super.visitEnd();
}
- /**
- * Ensures that the given member does not correspond to a internal member
- * created by the instrumentation process. This would mean that the class
- * has been instrumented twice.
- *
- * @param member
- * name of the member to check
- * @param instrMember
- * name of a instrumentation member
- * @throws IllegalStateException
- * thrown if the member has the same name than the
- * instrumentation member
- */
- private void assertNotInstrumented(final String member,
- final String instrMember) throws IllegalStateException {
- if (member.equals(instrMember)) {
- throw new IllegalStateException(format(
- "Class %s is already instrumented.", className));
- }
- }
-
// === probe array strategies ===
private class ClassTypeStrategy implements IProbeArrayStrategy {
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 8bb46026..8c74a4b8 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
@@ -11,6 +11,8 @@
*******************************************************************************/
package org.jacoco.core.internal.instr;
+import static java.lang.String.format;
+
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
@@ -61,6 +63,27 @@ public final class InstrSupport {
| Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL;
/**
+ * Ensures that the given member does not correspond to a internal member
+ * created by the instrumentation process. This would mean that the class is
+ * already instrumented.
+ *
+ * @param member
+ * name of the member to check
+ * @param owner
+ * name of the class owning the member
+ * @throws IllegalStateException
+ * thrown if the member has the same name than the
+ * instrumentation member
+ */
+ public static void assertNotInstrumented(final String member,
+ final String owner) throws IllegalStateException {
+ if (member.equals(DATAFIELD_NAME) || member.equals(INITMETHOD_NAME)) {
+ throw new IllegalStateException(format(
+ "Class %s is already instrumented.", owner));
+ }
+ }
+
+ /**
* Generates the instruction to push the given int value on the stack.
* Implementation taken from
* {@link org.objectweb.asm.commons.GeneratorAdapter#push(int)}.
diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html
index a002b95e..306c6716 100644
--- a/org.jacoco.doc/docroot/doc/changes.html
+++ b/org.jacoco.doc/docroot/doc/changes.html
@@ -38,6 +38,8 @@
<ul>
<li>More context information when exceptions occur during analysis or
instrumentation (GitHub #104).</li>
+ <li>If analysis is performed on offline instrumented classes - which is an
+ build configuration error - an exception is now thrown (GitHub #108).</li>
</ul>