1 /******************************************************************************* 2 * Copyright (c) 2009, 2021 Mountainminds GmbH & Co. KG and Contributors 3 * This program and the accompanying materials are made available under 4 * the terms of the Eclipse Public License 2.0 which is available at 5 * http://www.eclipse.org/legal/epl-2.0 6 * 7 * SPDX-License-Identifier: EPL-2.0 8 * 9 * Contributors: 10 * Nikolay Krasko - initial API and implementation 11 * 12 *******************************************************************************/ 13 package org.jacoco.core.internal.analysis.filter; 14 15 import org.objectweb.asm.tree.AbstractInsnNode; 16 import org.objectweb.asm.tree.MethodNode; 17 18 /** 19 * Filters methods generated by the Kotlin compiler. Kotlin classes are 20 * identified by the <code>@kotlin.Metadata</code> annotations. In such classes 21 * generated methods do not have line numbers. 22 */ 23 public class KotlinGeneratedFilter implements IFilter { 24 25 static final String KOTLIN_METADATA_DESC = "Lkotlin/Metadata;"; 26 isKotlinClass(final IFilterContext context)27 static boolean isKotlinClass(final IFilterContext context) { 28 return context.getClassAnnotations().contains(KOTLIN_METADATA_DESC); 29 } 30 filter(final MethodNode methodNode, final IFilterContext context, final IFilterOutput output)31 public void filter(final MethodNode methodNode, 32 final IFilterContext context, final IFilterOutput output) { 33 34 if (context.getSourceFileName() == null) { 35 // probably full debug information is missing 36 // disabled filtering as all methods might be erroneously skipped 37 return; 38 } 39 40 if (!isKotlinClass(context)) { 41 return; 42 } 43 44 if (hasLineNumber(methodNode)) { 45 return; 46 } 47 48 output.ignore(methodNode.instructions.getFirst(), 49 methodNode.instructions.getLast()); 50 } 51 hasLineNumber(final MethodNode methodNode)52 private boolean hasLineNumber(final MethodNode methodNode) { 53 for (final AbstractInsnNode i : methodNode.instructions) { 54 if (AbstractInsnNode.LINE == i.getType()) { 55 return true; 56 } 57 } 58 return false; 59 } 60 61 } 62