aboutsummaryrefslogtreecommitdiff
path: root/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter
diff options
context:
space:
mode:
Diffstat (limited to 'org.jacoco.core/src/org/jacoco/core/internal/analysis/filter')
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/AbstractMatcher.java13
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/AnnotationGeneratedFilter.java11
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/BridgeFilter.java32
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/EnumEmptyConstructorFilter.java11
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/EnumFilter.java11
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/Filters.java22
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/FinallyFilter.java15
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/IFilter.java11
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/IFilterContext.java102
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/IFilterOutput.java13
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilter.java53
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultArgumentsFilter.java95
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultMethodsFilter.java46
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinGeneratedFilter.java14
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinInlineFilter.java20
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinLateinitFilter.java24
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinNotNullOperatorFilter.java14
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinUnsafeCastOperatorFilter.java37
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinWhenFilter.java19
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinWhenStringFilter.java44
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/PrivateEmptyNoArgConstructorFilter.java11
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/RecordsFilter.java89
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/StringSwitchFilter.java (renamed from org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/StringSwitchEcjFilter.java)26
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/StringSwitchJavacFilter.java15
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/SynchronizedFilter.java11
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/SyntheticFilter.java32
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/TryWithResourcesEcjFilter.java11
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/TryWithResourcesJavac11Filter.java13
-rw-r--r--org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/TryWithResourcesJavacFilter.java13
29 files changed, 573 insertions, 255 deletions
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/AbstractMatcher.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/AbstractMatcher.java
index 38860a83..837278e9 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/AbstractMatcher.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/AbstractMatcher.java
@@ -1,9 +1,10 @@
/*******************************************************************************
- * Copyright (c) 2009, 2019 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
+ * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Evgeny Mandrikov - initial API and implementation
@@ -34,7 +35,7 @@ abstract class AbstractMatcher {
final void firstIsALoad0(final MethodNode methodNode) {
cursor = methodNode.instructions.getFirst();
skipNonOpcodes();
- if (cursor.getOpcode() == Opcodes.ALOAD
+ if (cursor != null && cursor.getOpcode() == Opcodes.ALOAD
&& ((VarInsnNode) cursor).var == 0) {
return;
}
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/AnnotationGeneratedFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/AnnotationGeneratedFilter.java
index d78444c0..1653fa27 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/AnnotationGeneratedFilter.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/AnnotationGeneratedFilter.java
@@ -1,9 +1,10 @@
/*******************************************************************************
- * Copyright (c) 2009, 2019 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
+ * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Evgeny Mandrikov - initial API and implementation
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/BridgeFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/BridgeFilter.java
new file mode 100644
index 00000000..bc23941b
--- /dev/null
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/BridgeFilter.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Evgeny Mandrikov - initial API and implementation
+ *
+ *******************************************************************************/
+package org.jacoco.core.internal.analysis.filter;
+
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.tree.MethodNode;
+
+/**
+ * Filters bridge methods.
+ */
+final class BridgeFilter implements IFilter {
+
+ public void filter(final MethodNode methodNode,
+ final IFilterContext context, final IFilterOutput output) {
+ if ((methodNode.access & Opcodes.ACC_BRIDGE) == 0) {
+ return;
+ }
+ output.ignore(methodNode.instructions.getFirst(),
+ methodNode.instructions.getLast());
+ }
+
+}
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/EnumEmptyConstructorFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/EnumEmptyConstructorFilter.java
index 4a39d1e8..ae23c641 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/EnumEmptyConstructorFilter.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/EnumEmptyConstructorFilter.java
@@ -1,9 +1,10 @@
/*******************************************************************************
- * Copyright (c) 2009, 2019 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
+ * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Evgeny Mandrikov - initial API and implementation
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/EnumFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/EnumFilter.java
index 0c2eef58..faab0ad4 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/EnumFilter.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/EnumFilter.java
@@ -1,9 +1,10 @@
/*******************************************************************************
- * Copyright (c) 2009, 2019 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
+ * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Evgeny Mandrikov - initial API and implementation
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/Filters.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/Filters.java
index 7a1053b5..484ccc00 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/Filters.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/Filters.java
@@ -1,9 +1,10 @@
/*******************************************************************************
- * Copyright (c) 2009, 2019 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
+ * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Evgeny Mandrikov - initial API and implementation
@@ -27,24 +28,25 @@ public final class Filters implements IFilter {
/**
* Creates filter that combines all other filters.
- *
+ *
* @return filter that combines all other filters
*/
public static IFilter all() {
return new Filters(new EnumFilter(), new SyntheticFilter(),
- new SynchronizedFilter(), new TryWithResourcesJavac11Filter(),
+ new BridgeFilter(), new SynchronizedFilter(),
+ new TryWithResourcesJavac11Filter(),
new TryWithResourcesJavacFilter(),
new TryWithResourcesEcjFilter(), new FinallyFilter(),
new PrivateEmptyNoArgConstructorFilter(),
- new StringSwitchJavacFilter(), new StringSwitchEcjFilter(),
- new EnumEmptyConstructorFilter(),
+ new StringSwitchJavacFilter(), new StringSwitchFilter(),
+ new EnumEmptyConstructorFilter(), new RecordsFilter(),
new AnnotationGeneratedFilter(), new KotlinGeneratedFilter(),
new KotlinLateinitFilter(), new KotlinWhenFilter(),
new KotlinWhenStringFilter(),
new KotlinUnsafeCastOperatorFilter(),
new KotlinNotNullOperatorFilter(),
new KotlinDefaultArgumentsFilter(), new KotlinInlineFilter(),
- new KotlinCoroutineFilter());
+ new KotlinCoroutineFilter(), new KotlinDefaultMethodsFilter());
}
private Filters(final IFilter... filters) {
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/FinallyFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/FinallyFilter.java
index b2e0b145..284d4322 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/FinallyFilter.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/FinallyFilter.java
@@ -1,9 +1,10 @@
/*******************************************************************************
- * Copyright (c) 2009, 2019 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
+ * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Evgeny Mandrikov - initial API and implementation
@@ -26,7 +27,7 @@ import org.objectweb.asm.tree.VarInsnNode;
* Filters duplicates of finally blocks that compiler generates.
*
* To understand algorithm of filtering, consider following example:
- *
+ *
* <pre>
* try {
* if (x) {
@@ -44,7 +45,7 @@ import org.objectweb.asm.tree.VarInsnNode;
* There are 4 <b>distinct</b> points of exit out of these "try/catch/finally"
* blocks - three without exception, and one with Throwable if it is thrown
* prior to reaching first three points of exit.
- *
+ *
* "finally" block must be executed just before these points, so there must be 4
* copies of its bytecode instructions.
*
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/IFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/IFilter.java
index b662ba4f..9f0a7589 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/IFilter.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/IFilter.java
@@ -1,9 +1,10 @@
/*******************************************************************************
- * Copyright (c) 2009, 2019 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
+ * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Evgeny Mandrikov - initial API and implementation
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/IFilterContext.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/IFilterContext.java
index 8b97654d..992e3e8d 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/IFilterContext.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/IFilterContext.java
@@ -1,48 +1,54 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2019 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.filter;
-
-import java.util.Set;
-
-/**
- * Context information provided to filters.
- */
-public interface IFilterContext {
-
- /**
- * @return vm name of the enclosing class
- */
- String getClassName();
-
- /**
- * @return vm name of the super class of the enclosing class
- */
- String getSuperClassName();
-
- /**
- * @return vm names of the class annotations of the enclosing class
- */
- Set<String> getClassAnnotations();
-
- /**
- * @return file name of the corresponding source file or <code>null</code>
- * if not available
- */
- String getSourceFileName();
-
- /**
- * @return value of SourceDebugExtension attribute or <code>null</code> if
- * not available
- */
- String getSourceDebugExtension();
-
-}
+/*******************************************************************************
+ * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Marc R. Hoffmann - initial API and implementation
+ *
+ *******************************************************************************/
+package org.jacoco.core.internal.analysis.filter;
+
+import java.util.Set;
+
+/**
+ * Context information provided to filters.
+ */
+public interface IFilterContext {
+
+ /**
+ * @return vm name of the enclosing class
+ */
+ String getClassName();
+
+ /**
+ * @return vm name of the super class of the enclosing class
+ */
+ String getSuperClassName();
+
+ /**
+ * @return vm names of the class annotations of the enclosing class
+ */
+ Set<String> getClassAnnotations();
+
+ /**
+ * @return names of the class attributes
+ */
+ Set<String> getClassAttributes();
+
+ /**
+ * @return file name of the corresponding source file or <code>null</code>
+ * if not available
+ */
+ String getSourceFileName();
+
+ /**
+ * @return value of SourceDebugExtension attribute or <code>null</code> if
+ * not available
+ */
+ String getSourceDebugExtension();
+
+}
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/IFilterOutput.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/IFilterOutput.java
index 0f022201..93ad2eeb 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/IFilterOutput.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/IFilterOutput.java
@@ -1,9 +1,10 @@
/*******************************************************************************
- * Copyright (c) 2009, 2019 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
+ * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Evgeny Mandrikov - initial API and implementation
@@ -35,7 +36,7 @@ public interface IFilterOutput {
/**
* Marks two instructions that should be merged during computation of
* coverage.
- *
+ *
* @param i1
* first instruction
* @param i2
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilter.java
index 66d450a3..4b850f33 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilter.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinCoroutineFilter.java
@@ -1,9 +1,10 @@
/*******************************************************************************
- * Copyright (c) 2009, 2019 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
+ * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Evgeny Mandrikov - initial API and implementation
@@ -19,6 +20,7 @@ import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.JumpInsnNode;
import org.objectweb.asm.tree.LdcInsnNode;
+import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.TableSwitchInsnNode;
@@ -27,7 +29,11 @@ import org.objectweb.asm.tree.TableSwitchInsnNode;
*/
public final class KotlinCoroutineFilter implements IFilter {
- static boolean isLastArgumentContinuation(final MethodNode methodNode) {
+ static boolean isImplementationOfSuspendFunction(
+ final MethodNode methodNode) {
+ if (methodNode.name.startsWith("access$")) {
+ return false;
+ }
final Type methodType = Type.getMethodType(methodNode.desc);
final int lastArgument = methodType.getArgumentTypes().length - 1;
return lastArgument >= 0 && "kotlin.coroutines.Continuation".equals(
@@ -42,16 +48,41 @@ public final class KotlinCoroutineFilter implements IFilter {
}
new Matcher().match(methodNode, output);
-
+ new Matcher().matchOptimizedTailCall(methodNode, output);
}
private static class Matcher extends AbstractMatcher {
+
+ private void matchOptimizedTailCall(final MethodNode methodNode,
+ final IFilterOutput output) {
+ for (final AbstractInsnNode i : methodNode.instructions) {
+ cursor = i;
+ nextIs(Opcodes.DUP);
+ nextIsInvoke(Opcodes.INVOKESTATIC,
+ "kotlin/coroutines/intrinsics/IntrinsicsKt",
+ "getCOROUTINE_SUSPENDED", "()Ljava/lang/Object;");
+ nextIs(Opcodes.IF_ACMPNE);
+ nextIs(Opcodes.ARETURN);
+ nextIs(Opcodes.POP);
+ if (cursor != null) {
+ output.ignore(i.getNext(), cursor);
+ }
+ }
+ }
+
private void match(final MethodNode methodNode,
final IFilterOutput output) {
- cursor = methodNode.instructions.getFirst();
- nextIsInvoke(Opcodes.INVOKESTATIC,
- "kotlin/coroutines/intrinsics/IntrinsicsKt",
- "getCOROUTINE_SUSPENDED", "()Ljava/lang/Object;");
+ cursor = skipNonOpcodes(methodNode.instructions.getFirst());
+ if (cursor == null || cursor.getOpcode() != Opcodes.INVOKESTATIC) {
+ cursor = null;
+ } else {
+ final MethodInsnNode m = (MethodInsnNode) cursor;
+ if (!"kotlin/coroutines/intrinsics/IntrinsicsKt".equals(m.owner)
+ || !"getCOROUTINE_SUSPENDED".equals(m.name)
+ || !"()Ljava/lang/Object;".equals(m.desc)) {
+ cursor = null;
+ }
+ }
if (cursor == null) {
cursor = skipNonOpcodes(methodNode.instructions.getFirst());
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultArgumentsFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultArgumentsFilter.java
index ef198447..b734d234 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultArgumentsFilter.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultArgumentsFilter.java
@@ -1,9 +1,10 @@
/*******************************************************************************
- * Copyright (c) 2009, 2019 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
+ * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Evgeny Mandrikov - initial API and implementation
@@ -18,15 +19,16 @@ import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.JumpInsnNode;
+import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.VarInsnNode;
/**
* Filters branches that Kotlin compiler generates for default arguments.
- *
+ *
* For each default argument Kotlin compiler generates following bytecode to
* determine if it should be used or not:
- *
+ *
* <pre>
* ILOAD maskVar
* ICONST_x, BIPUSH, SIPUSH, LDC or LDC_W
@@ -35,16 +37,30 @@ import org.objectweb.asm.tree.VarInsnNode;
* default argument
* label:
* </pre>
- *
+ *
* Where <code>maskVar</code> is penultimate argument of synthetic method with
- * suffix "$default". And its value can't be zero - invocation with all
- * arguments uses original non synthetic method, thus <code>IFEQ</code>
- * instructions should be ignored.
+ * suffix "$default" or of synthetic constructor with last argument
+ * "kotlin.jvm.internal.DefaultConstructorMarker". And its value can't be zero -
+ * invocation with all arguments uses original non synthetic method, thus
+ * <code>IFEQ</code> instructions should be ignored.
*/
public final class KotlinDefaultArgumentsFilter implements IFilter {
- static boolean isDefaultArgumentsMethodName(final String methodName) {
- return methodName.endsWith("$default");
+ static boolean isDefaultArgumentsMethod(final MethodNode methodNode) {
+ return methodNode.name.endsWith("$default");
+ }
+
+ static boolean isDefaultArgumentsConstructor(final MethodNode methodNode) {
+ if (!"<init>".equals(methodNode.name)) {
+ return false;
+ }
+ final Type[] argumentTypes = Type.getMethodType(methodNode.desc)
+ .getArgumentTypes();
+ if (argumentTypes.length < 2) {
+ return false;
+ }
+ return "kotlin.jvm.internal.DefaultConstructorMarker"
+ .equals(argumentTypes[argumentTypes.length - 1].getClassName());
}
public void filter(final MethodNode methodNode,
@@ -52,24 +68,45 @@ public final class KotlinDefaultArgumentsFilter implements IFilter {
if ((methodNode.access & Opcodes.ACC_SYNTHETIC) == 0) {
return;
}
- if (!isDefaultArgumentsMethodName(methodNode.name)) {
- return;
- }
if (!KotlinGeneratedFilter.isKotlinClass(context)) {
return;
}
- new Matcher().match(methodNode, output);
+ if (isDefaultArgumentsMethod(methodNode)) {
+ new Matcher().match(methodNode, output, false);
+ } else if (isDefaultArgumentsConstructor(methodNode)) {
+ new Matcher().match(methodNode, output, true);
+ }
}
private static class Matcher extends AbstractMatcher {
public void match(final MethodNode methodNode,
- final IFilterOutput output) {
- cursor = methodNode.instructions.getFirst();
+ final IFilterOutput output, final boolean constructor) {
+ cursor = skipNonOpcodes(methodNode.instructions.getFirst());
+
+ nextIs(Opcodes.IFNULL);
+ nextIsType(Opcodes.NEW, "java/lang/UnsupportedOperationException");
+ nextIs(Opcodes.DUP);
+ nextIs(Opcodes.LDC);
+ if (cursor == null
+ || !(((LdcInsnNode) cursor).cst instanceof String)
+ || !(((String) ((LdcInsnNode) cursor).cst).startsWith(
+ "Super calls with default arguments not supported in this target"))) {
+ cursor = null;
+ }
+ nextIsInvoke(Opcodes.INVOKESPECIAL,
+ "java/lang/UnsupportedOperationException", "<init>",
+ "(Ljava/lang/String;)V");
+ nextIs(Opcodes.ATHROW);
+ if (cursor != null) {
+ output.ignore(methodNode.instructions.getFirst(), cursor);
+ next();
+ } else {
+ cursor = skipNonOpcodes(methodNode.instructions.getFirst());
+ }
final Set<AbstractInsnNode> ignore = new HashSet<AbstractInsnNode>();
- final int maskVar = Type.getMethodType(methodNode.desc)
- .getArgumentTypes().length - 2;
+ final int maskVar = maskVar(methodNode.desc, constructor);
while (true) {
if (cursor.getOpcode() != Opcodes.ILOAD) {
break;
@@ -92,6 +129,22 @@ public final class KotlinDefaultArgumentsFilter implements IFilter {
output.ignore(i, i);
}
}
+
+ private static int maskVar(final String desc,
+ final boolean constructor) {
+ int slot = 0;
+ if (constructor) {
+ // one slot for reference to current object
+ slot++;
+ }
+ final Type[] argumentTypes = Type.getMethodType(desc)
+ .getArgumentTypes();
+ final int penultimateArgument = argumentTypes.length - 2;
+ for (int i = 0; i < penultimateArgument; i++) {
+ slot += argumentTypes[i].getSize();
+ }
+ return slot;
+ }
}
}
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultMethodsFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultMethodsFilter.java
new file mode 100644
index 00000000..50d6280e
--- /dev/null
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinDefaultMethodsFilter.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Evgeny Mandrikov - initial API and implementation
+ *
+ *******************************************************************************/
+package org.jacoco.core.internal.analysis.filter;
+
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.tree.MethodInsnNode;
+import org.objectweb.asm.tree.MethodNode;
+
+/**
+ * Filters methods that Kotlin compiler generates for non-overridden
+ * non-abstract methods of interfaces.
+ */
+final class KotlinDefaultMethodsFilter implements IFilter {
+
+ public void filter(final MethodNode methodNode,
+ final IFilterContext context, final IFilterOutput output) {
+ if (!KotlinGeneratedFilter.isKotlinClass(context)) {
+ return;
+ }
+ new Matcher().match(methodNode, output);
+ }
+
+ private static class Matcher extends AbstractMatcher {
+ private void match(final MethodNode methodNode,
+ final IFilterOutput output) {
+ firstIsALoad0(methodNode);
+ nextIs(Opcodes.INVOKESTATIC);
+ if (cursor != null && ((MethodInsnNode) cursor).owner
+ .endsWith("$DefaultImpls")) {
+ output.ignore(methodNode.instructions.getFirst(),
+ methodNode.instructions.getLast());
+ }
+ }
+ }
+
+}
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinGeneratedFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinGeneratedFilter.java
index 129580a9..4ebc3707 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinGeneratedFilter.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinGeneratedFilter.java
@@ -1,9 +1,10 @@
/*******************************************************************************
- * Copyright (c) 2009, 2019 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
+ * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Nikolay Krasko - initial API and implementation
@@ -49,8 +50,7 @@ public class KotlinGeneratedFilter implements IFilter {
}
private boolean hasLineNumber(final MethodNode methodNode) {
- for (AbstractInsnNode i = methodNode.instructions
- .getFirst(); i != null; i = i.getNext()) {
+ for (final AbstractInsnNode i : methodNode.instructions) {
if (AbstractInsnNode.LINE == i.getType()) {
return true;
}
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinInlineFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinInlineFilter.java
index 5666de2d..f3e7d6b9 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinInlineFilter.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinInlineFilter.java
@@ -1,9 +1,10 @@
/*******************************************************************************
- * Copyright (c) 2009, 2019 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
+ * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Evgeny Mandrikov - initial API and implementation
@@ -46,8 +47,7 @@ public final class KotlinInlineFilter implements IFilter {
}
int line = 0;
- for (AbstractInsnNode i = methodNode.instructions
- .getFirst(); i != null; i = i.getNext()) {
+ for (final AbstractInsnNode i : methodNode.instructions) {
if (AbstractInsnNode.LINE == i.getType()) {
line = ((LineNumberNode) i).line;
}
@@ -92,7 +92,11 @@ public final class KotlinInlineFilter implements IFilter {
}
// LineSection
int min = Integer.MAX_VALUE;
- while (!"*E".equals(line = br.readLine())) {
+ while (true) {
+ line = br.readLine();
+ if (line.equals("*E") || line.equals("*S KotlinDebug")) {
+ break;
+ }
final Matcher m = LINE_INFO_PATTERN.matcher(line);
if (!m.matches()) {
throw new IllegalStateException(
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinLateinitFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinLateinitFilter.java
index 12fe926c..a5e20265 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinLateinitFilter.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinLateinitFilter.java
@@ -1,9 +1,10 @@
/*******************************************************************************
- * Copyright (c) 2009, 2019 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
+ * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Fabian Mastenbroek - initial API and implementation
@@ -13,6 +14,7 @@ package org.jacoco.core.internal.analysis.filter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.JumpInsnNode;
import org.objectweb.asm.tree.MethodNode;
/**
@@ -24,9 +26,8 @@ public class KotlinLateinitFilter implements IFilter {
public void filter(final MethodNode methodNode,
final IFilterContext context, final IFilterOutput output) {
final Matcher matcher = new Matcher();
- for (AbstractInsnNode i = methodNode.instructions
- .getFirst(); i != null; i = i.getNext()) {
- matcher.match(i, output);
+ for (final AbstractInsnNode node : methodNode.instructions) {
+ matcher.match(node, output);
}
}
@@ -44,6 +45,13 @@ public class KotlinLateinitFilter implements IFilter {
"throwUninitializedPropertyAccessException",
"(Ljava/lang/String;)V");
+ if (cursor != null
+ && skipNonOpcodes(cursor.getNext()) != skipNonOpcodes(
+ ((JumpInsnNode) start).label)) {
+ nextIs(Opcodes.ACONST_NULL);
+ nextIs(Opcodes.ATHROW);
+ }
+
if (cursor != null) {
output.ignore(start, cursor);
}
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinNotNullOperatorFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinNotNullOperatorFilter.java
index 4dd223a3..dda54210 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinNotNullOperatorFilter.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinNotNullOperatorFilter.java
@@ -1,9 +1,10 @@
/*******************************************************************************
- * Copyright (c) 2009, 2019 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
+ * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Evgeny Mandrikov - initial API and implementation
@@ -24,8 +25,7 @@ public final class KotlinNotNullOperatorFilter implements IFilter {
public void filter(final MethodNode methodNode,
final IFilterContext context, final IFilterOutput output) {
final Matcher matcher = new Matcher();
- for (AbstractInsnNode i = methodNode.instructions
- .getFirst(); i != null; i = i.getNext()) {
+ for (final AbstractInsnNode i : methodNode.instructions) {
matcher.match(i, output);
}
}
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 c298e945..82522a8a 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
@@ -1,9 +1,10 @@
/*******************************************************************************
- * Copyright (c) 2009, 2019 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
+ * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Evgeny Mandrikov - initial API and implementation
@@ -23,27 +24,29 @@ import org.objectweb.asm.tree.MethodNode;
*/
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 (AbstractInsnNode i = methodNode.instructions
- .getFirst(); i != null; i = i.getNext()) {
- matcher.match(i, output);
+ for (final AbstractInsnNode i : methodNode.instructions) {
+ 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()) {
return;
}
cursor = start;
-
- nextIsType(Opcodes.NEW, KOTLIN_TYPE_CAST_EXCEPTION);
+ final JumpInsnNode jumpInsnNode = (JumpInsnNode) cursor;
+ nextIsType(Opcodes.NEW, exceptionType);
nextIs(Opcodes.DUP);
nextIs(Opcodes.LDC);
if (cursor == null) {
@@ -54,13 +57,13 @@ public final class KotlinUnsafeCastOperatorFilter implements IFilter {
.startsWith("null cannot be cast to non-null type"))) {
return;
}
- nextIsInvoke(Opcodes.INVOKESPECIAL, KOTLIN_TYPE_CAST_EXCEPTION,
- "<init>", "(Ljava/lang/String;)V");
+ nextIsInvoke(Opcodes.INVOKESPECIAL, exceptionType, "<init>",
+ "(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.core/src/org/jacoco/core/internal/analysis/filter/KotlinWhenFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinWhenFilter.java
index a229aa04..ba2fb95c 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinWhenFilter.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinWhenFilter.java
@@ -1,9 +1,10 @@
/*******************************************************************************
- * Copyright (c) 2009, 2019 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
+ * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Evgeny Mandrikov - initial API and implementation
@@ -17,7 +18,6 @@ import java.util.Set;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
-import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.JumpInsnNode;
import org.objectweb.asm.tree.LabelNode;
import org.objectweb.asm.tree.LookupSwitchInsnNode;
@@ -37,15 +37,14 @@ public final class KotlinWhenFilter implements IFilter {
public void filter(final MethodNode methodNode,
final IFilterContext context, final IFilterOutput output) {
final Matcher matcher = new Matcher();
- for (AbstractInsnNode i = methodNode.instructions
- .getFirst(); i != null; i = i.getNext()) {
+ for (final AbstractInsnNode i : methodNode.instructions) {
matcher.match(i, output);
}
}
private static class Matcher extends AbstractMatcher {
void match(final AbstractInsnNode start, final IFilterOutput output) {
- if (start.getType() != InsnNode.LABEL) {
+ if (start.getType() != AbstractInsnNode.LABEL) {
return;
}
cursor = start;
@@ -92,7 +91,7 @@ public final class KotlinWhenFilter implements IFilter {
labels = ((TableSwitchInsnNode) switchNode).labels;
}
final Set<AbstractInsnNode> newTargets = new HashSet<AbstractInsnNode>();
- for (LabelNode label : labels) {
+ for (final LabelNode label : labels) {
newTargets.add(AbstractMatcher.skipNonOpcodes(label));
}
output.replaceBranches(switchNode, newTargets);
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinWhenStringFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinWhenStringFilter.java
index fcccb550..5fd20874 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinWhenStringFilter.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/KotlinWhenStringFilter.java
@@ -1,9 +1,10 @@
/*******************************************************************************
- * Copyright (c) 2009, 2019 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
+ * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Evgeny Mandrikov - initial API and implementation
@@ -32,8 +33,7 @@ public final class KotlinWhenStringFilter implements IFilter {
public void filter(final MethodNode methodNode,
final IFilterContext context, final IFilterOutput output) {
final Matcher matcher = new Matcher();
- for (AbstractInsnNode i = methodNode.instructions
- .getFirst(); i != null; i = i.getNext()) {
+ for (final AbstractInsnNode i : methodNode.instructions) {
matcher.match(i, output);
}
}
@@ -67,10 +67,14 @@ public final class KotlinWhenStringFilter implements IFilter {
hashCodes = tableSwitch.labels.size();
}
+ if (hashCodes == 0) {
+ return;
+ }
+
final Set<AbstractInsnNode> replacements = new HashSet<AbstractInsnNode>();
replacements.add(skipNonOpcodes(defaultLabel));
- for (int i = 0; i < hashCodes; i++) {
+ for (int i = 1; i <= hashCodes; i++) {
while (true) {
nextIsVar(Opcodes.ALOAD, "s");
nextIs(Opcodes.LDC);
@@ -79,18 +83,24 @@ public final class KotlinWhenStringFilter implements IFilter {
// jump to next comparison or default case
nextIs(Opcodes.IFEQ);
final JumpInsnNode jump = (JumpInsnNode) cursor;
- // jump to case
- nextIs(Opcodes.GOTO);
+ next();
if (cursor == null) {
return;
- }
-
- replacements
- .add(skipNonOpcodes(((JumpInsnNode) cursor).label));
-
- if (jump.label == defaultLabel) {
- // end of comparisons for same hashCode
+ } else if (cursor.getOpcode() == Opcodes.GOTO) {
+ // jump to case body
+ replacements.add(
+ skipNonOpcodes(((JumpInsnNode) cursor).label));
+ if (jump.label == defaultLabel) {
+ // end of comparisons for same hashCode
+ break;
+ }
+ } else if (i == hashCodes && jump.label == defaultLabel) {
+ // case body
+ replacements.add(cursor);
+ cursor = jump;
break;
+ } else {
+ return;
}
}
}
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/PrivateEmptyNoArgConstructorFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/PrivateEmptyNoArgConstructorFilter.java
index 236ef712..4b22dc29 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/PrivateEmptyNoArgConstructorFilter.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/PrivateEmptyNoArgConstructorFilter.java
@@ -1,9 +1,10 @@
/*******************************************************************************
- * Copyright (c) 2009, 2019 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
+ * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Evgeny Mandrikov - initial API and implementation
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/RecordsFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/RecordsFilter.java
new file mode 100644
index 00000000..745848ba
--- /dev/null
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/RecordsFilter.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Evgeny Mandrikov - initial API and implementation
+ *
+ *******************************************************************************/
+package org.jacoco.core.internal.analysis.filter;
+
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.tree.InvokeDynamicInsnNode;
+import org.objectweb.asm.tree.MethodNode;
+
+/**
+ * Filters methods <code>toString</code>, <code>hashCode</code> and
+ * <code>equals</code> that compiler generates for records.
+ */
+public final class RecordsFilter implements IFilter {
+
+ public void filter(final MethodNode methodNode,
+ final IFilterContext context, final IFilterOutput output) {
+ if (!"java/lang/Record".equals(context.getSuperClassName())) {
+ return;
+ }
+ final Matcher matcher = new Matcher();
+ if (matcher.isEquals(methodNode) || matcher.isHashCode(methodNode)
+ || matcher.isToString(methodNode)) {
+ output.ignore(methodNode.instructions.getFirst(),
+ methodNode.instructions.getLast());
+ }
+ }
+
+ private static class Matcher extends AbstractMatcher {
+ boolean isToString(final MethodNode m) {
+ if (!"toString".equals(m.name)
+ || !"()Ljava/lang/String;".equals(m.desc)) {
+ return false;
+ }
+ firstIsALoad0(m);
+ nextIsInvokeDynamic("toString");
+ nextIs(Opcodes.ARETURN);
+ return cursor != null;
+ }
+
+ boolean isHashCode(final MethodNode m) {
+ if (!"hashCode".equals(m.name) || !"()I".equals(m.desc)) {
+ return false;
+ }
+ firstIsALoad0(m);
+ nextIsInvokeDynamic("hashCode");
+ nextIs(Opcodes.IRETURN);
+ return cursor != null;
+ }
+
+ boolean isEquals(final MethodNode m) {
+ if (!"equals".equals(m.name)
+ || !"(Ljava/lang/Object;)Z".equals(m.desc)) {
+ return false;
+ }
+ firstIsALoad0(m);
+ nextIs(Opcodes.ALOAD);
+ nextIsInvokeDynamic("equals");
+ nextIs(Opcodes.IRETURN);
+ return cursor != null;
+ }
+
+ private void nextIsInvokeDynamic(final String name) {
+ nextIs(Opcodes.INVOKEDYNAMIC);
+ if (cursor == null) {
+ return;
+ }
+ final InvokeDynamicInsnNode i = (InvokeDynamicInsnNode) cursor;
+ final Handle bsm = i.bsm;
+ if (name.equals(i.name)
+ && "java/lang/runtime/ObjectMethods".equals(bsm.getOwner())
+ && "bootstrap".equals(bsm.getName())) {
+ return;
+ }
+ cursor = null;
+ }
+ }
+
+}
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/StringSwitchEcjFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/StringSwitchFilter.java
index e0aba35d..a78e253e 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/StringSwitchEcjFilter.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/StringSwitchFilter.java
@@ -1,9 +1,10 @@
/*******************************************************************************
- * Copyright (c) 2009, 2019 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
+ * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Evgeny Mandrikov - initial API and implementation
@@ -25,15 +26,15 @@ import org.objectweb.asm.tree.VarInsnNode;
/**
* Filters code that is generated by ECJ for a <code>switch</code> statement
- * with a <code>String</code>.
+ * with a <code>String</code> and by Kotlin compiler 1.5 and above for a
+ * <code>when</code> expression with a <code>String</code>.
*/
-public final class StringSwitchEcjFilter implements IFilter {
+public final class StringSwitchFilter implements IFilter {
public void filter(final MethodNode methodNode,
final IFilterContext context, final IFilterOutput output) {
final Matcher matcher = new Matcher();
- for (AbstractInsnNode i = methodNode.instructions
- .getFirst(); i != null; i = i.getNext()) {
+ for (final AbstractInsnNode i : methodNode.instructions) {
matcher.match(i, output);
}
}
@@ -42,7 +43,8 @@ public final class StringSwitchEcjFilter implements IFilter {
public void match(final AbstractInsnNode start,
final IFilterOutput output) {
- if (Opcodes.ASTORE != start.getOpcode()) {
+ if (start.getOpcode() != /* ECJ */ Opcodes.ASTORE
+ && start.getOpcode() != /* Kotlin */ Opcodes.ALOAD) {
return;
}
cursor = start;
@@ -67,6 +69,10 @@ public final class StringSwitchEcjFilter implements IFilter {
hashCodes = tableSwitch.labels.size();
}
+ if (hashCodes == 0) {
+ return;
+ }
+
final Set<AbstractInsnNode> replacements = new HashSet<AbstractInsnNode>();
replacements.add(skipNonOpcodes(defaultLabel));
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/StringSwitchJavacFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/StringSwitchJavacFilter.java
index 3033d9bc..a5baf34c 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/StringSwitchJavacFilter.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/StringSwitchJavacFilter.java
@@ -1,9 +1,10 @@
/*******************************************************************************
- * Copyright (c) 2009, 2019 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
+ * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Evgeny Mandrikov - initial API and implementation
@@ -26,10 +27,8 @@ public final class StringSwitchJavacFilter implements IFilter {
public void filter(final MethodNode methodNode,
final IFilterContext context, final IFilterOutput output) {
- AbstractInsnNode i = methodNode.instructions.getFirst();
- while (i != null) {
+ for (final AbstractInsnNode i : methodNode.instructions) {
filter(i, output);
- i = i.getNext();
}
}
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/SynchronizedFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/SynchronizedFilter.java
index 6341328f..abc9e45b 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/SynchronizedFilter.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/SynchronizedFilter.java
@@ -1,9 +1,10 @@
/*******************************************************************************
- * Copyright (c) 2009, 2019 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
+ * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Evgeny Mandrikov - initial API and implementation
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/SyntheticFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/SyntheticFilter.java
index 69c4092a..127f7b03 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/SyntheticFilter.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/SyntheticFilter.java
@@ -1,9 +1,10 @@
/*******************************************************************************
- * Copyright (c) 2009, 2019 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
+ * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Evgeny Mandrikov - initial API and implementation
@@ -19,6 +20,11 @@ import org.objectweb.asm.tree.MethodNode;
*/
public final class SyntheticFilter implements IFilter {
+ private static boolean isScalaClass(final IFilterContext context) {
+ return context.getClassAttributes().contains("ScalaSig")
+ || context.getClassAttributes().contains("Scala");
+ }
+
public void filter(final MethodNode methodNode,
final IFilterContext context, final IFilterOutput output) {
if ((methodNode.access & Opcodes.ACC_SYNTHETIC) == 0) {
@@ -29,13 +35,25 @@ public final class SyntheticFilter implements IFilter {
return;
}
+ if (isScalaClass(context)) {
+ if (methodNode.name.startsWith("$anonfun$")) {
+ return;
+ }
+ }
+
if (KotlinGeneratedFilter.isKotlinClass(context)) {
if (KotlinDefaultArgumentsFilter
- .isDefaultArgumentsMethodName(methodNode.name)) {
+ .isDefaultArgumentsMethod(methodNode)) {
+ return;
+ }
+
+ if (KotlinDefaultArgumentsFilter
+ .isDefaultArgumentsConstructor(methodNode)) {
return;
}
- if (KotlinCoroutineFilter.isLastArgumentContinuation(methodNode)) {
+ if (KotlinCoroutineFilter
+ .isImplementationOfSuspendFunction(methodNode)) {
return;
}
}
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/TryWithResourcesEcjFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/TryWithResourcesEcjFilter.java
index 94dea561..714ab223 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/TryWithResourcesEcjFilter.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/TryWithResourcesEcjFilter.java
@@ -1,9 +1,10 @@
/*******************************************************************************
- * Copyright (c) 2009, 2019 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
+ * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Evgeny Mandrikov - initial API and implementation
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/TryWithResourcesJavac11Filter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/TryWithResourcesJavac11Filter.java
index 7a20f74f..0b451750 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/TryWithResourcesJavac11Filter.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/TryWithResourcesJavac11Filter.java
@@ -1,9 +1,10 @@
/*******************************************************************************
- * Copyright (c) 2009, 2019 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
+ * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Evgeny Mandrikov - initial API and implementation
@@ -55,7 +56,7 @@ public final class TryWithResourcesJavac11Filter implements IFilter {
* throw primaryExc;
* }
* </pre>
- *
+ *
* <code>null</code> check for resource is omitted when it is initialized
* using <code>new</code>
*/
diff --git a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/TryWithResourcesJavacFilter.java b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/TryWithResourcesJavacFilter.java
index 23ecb0e6..c3a0fa32 100644
--- a/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/TryWithResourcesJavacFilter.java
+++ b/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/TryWithResourcesJavacFilter.java
@@ -1,9 +1,10 @@
/*******************************************************************************
- * Copyright (c) 2009, 2019 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
+ * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors
+ * This program and the accompanying materials are made available under
+ * the terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Evgeny Mandrikov - initial API and implementation
@@ -47,7 +48,7 @@ public final class TryWithResourcesJavacFilter implements IFilter {
* compilation of source code that is described in <a href=
* "http://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.20.3.1">JLS
* 14.20.3. try-with-resources</a>:
- *
+ *
* <pre>
* Resource r = ...;
* Throwable primaryExc = null;