",
+ "(Ljava/lang/String;)V", false);
+ m.visitInsn(Opcodes.ATHROW);
+ final AbstractInsnNode expectedTo = m.instructions.getLast();
+ m.visitLabel(label);
+
+ filter.filter(m, context, output);
+
+ assertIgnored(new Range(expectedFrom, expectedTo));
+ }
+
+ /**
+ *
+ * fun f(o: Any?) {
+ * if (o == null)
+ * throw NullPointerException("null cannot be cast to non-null type")
+ * }
+ *
+ */
+ @Test
+ public void should_not_filter() {
+ context.classAnnotations
+ .add(KotlinGeneratedFilter.KOTLIN_METADATA_DESC);
+ m.visitVarInsn(Opcodes.ALOAD, 1);
+ final Label label = new Label();
+ m.visitJumpInsn(Opcodes.IFNONNULL, label);
+ m.visitTypeInsn(Opcodes.NEW, "java/lang/NullPointerException");
+ m.visitInsn(Opcodes.DUP);
+ m.visitLdcInsn("null cannot be cast to non-null type");
+ m.visitMethodInsn(Opcodes.INVOKESPECIAL,
+ "java/lang/NullPointerException", "",
+ "(Ljava/lang/String;)V", false);
+ m.visitInsn(Opcodes.ATHROW);
+ m.visitLabel(label);
+ m.visitInsn(Opcodes.RETURN);
+
+ filter.filter(m, context, output);
+
+ assertIgnored();
+ }
+
+ @Test
+ public void should_not_filter_when_not_kotlin() {
+ m.visitInsn(Opcodes.DUP);
+ final Label label = new Label();
+ m.visitJumpInsn(Opcodes.IFNONNULL, label);
+ m.visitTypeInsn(Opcodes.NEW, "java/lang/NullPointerException");
+ m.visitInsn(Opcodes.DUP);
+ m.visitLdcInsn("null cannot be cast to non-null type kotlin.String");
+ m.visitMethodInsn(Opcodes.INVOKESPECIAL,
+ "java/lang/NullPointerException", "",
+ "(Ljava/lang/String;)V", false);
+ m.visitInsn(Opcodes.ATHROW);
+ m.visitLabel(label);
+
+ filter.filter(m, context, output);
+
+ assertIgnored();
+ }
+
}
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinUnsafeCastOperatorFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinUnsafeCastOperatorFilter.java
index 3bfc27b0e5..f4aaa7f145 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinUnsafeCastOperatorFilter.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinUnsafeCastOperatorFilter.java
@@ -24,26 +24,30 @@
*/
public final class KotlinUnsafeCastOperatorFilter implements IFilter {
- private static final String KOTLIN_TYPE_CAST_EXCEPTION = "kotlin/TypeCastException";
-
public void filter(final MethodNode methodNode,
final IFilterContext context, final IFilterOutput output) {
+ if (!KotlinGeneratedFilter.isKotlinClass(context)) {
+ return;
+ }
final Matcher matcher = new Matcher();
for (final AbstractInsnNode i : methodNode.instructions) {
- matcher.match(i, output);
+ matcher.match("kotlin/TypeCastException", i, output);
+ // Since Kotlin 1.4.0:
+ matcher.match("java/lang/NullPointerException", i, output);
}
}
private static class Matcher extends AbstractMatcher {
- public void match(final AbstractInsnNode start,
- final IFilterOutput output) {
+ public void match(final String exceptionType,
+ final AbstractInsnNode start, final IFilterOutput output) {
- if (Opcodes.IFNONNULL != start.getOpcode()) {
+ if (Opcodes.DUP != start.getOpcode()) {
return;
}
cursor = start;
-
- nextIsType(Opcodes.NEW, KOTLIN_TYPE_CAST_EXCEPTION);
+ nextIs(Opcodes.IFNONNULL);
+ final JumpInsnNode jumpInsnNode = (JumpInsnNode) cursor;
+ nextIsType(Opcodes.NEW, exceptionType);
nextIs(Opcodes.DUP);
nextIs(Opcodes.LDC);
if (cursor == null) {
@@ -54,13 +58,13 @@ public void match(final AbstractInsnNode start,
.startsWith("null cannot be cast to non-null type"))) {
return;
}
- nextIsInvoke(Opcodes.INVOKESPECIAL, KOTLIN_TYPE_CAST_EXCEPTION,
- "", "(Ljava/lang/String;)V");
+ nextIsInvoke(Opcodes.INVOKESPECIAL, exceptionType, "",
+ "(Ljava/lang/String;)V");
nextIs(Opcodes.ATHROW);
if (cursor == null) {
return;
}
- if (cursor.getNext() != ((JumpInsnNode) start).label) {
+ if (cursor.getNext() != jumpInsnNode.label) {
return;
}
diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html
index a75d1f4daa..5d20c4a687 100644
--- a/org.jacoco.doc/docroot/doc/changes.html
+++ b/org.jacoco.doc/docroot/doc/changes.html
@@ -27,6 +27,9 @@ New Features
#1097).
Experimental support for Java 17 class files
(GitHub #1132).
+ Branch added by the Kotlin compiler version 1.4.0 and above for "unsafe" cast
+ operator is filtered out during generation of report
+ (GitHub #1143).
Non-functional Changes