172793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann/******************************************************************************* 2398ee59bebad6835dab57b60157eff16d511709eMarc R. Hoffmann * Copyright (c) 2009, 2015 Mountainminds GmbH & Co. KG and Contributors 372793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann * All rights reserved. This program and the accompanying materials 472793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann * are made available under the terms of the Eclipse Public License v1.0 572793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann * which accompanies this distribution, and is available at 672793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann * http://www.eclipse.org/legal/epl-v10.html 772793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann * 872793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann * Contributors: 972793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann * Marc R. Hoffmann - initial API and implementation 1072793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann * 1172793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann *******************************************************************************/ 1272793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmannpackage org.jacoco.core.internal.instr; 1372793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann 1472793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmannimport org.jacoco.core.internal.data.CRC64; 1572793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmannimport org.jacoco.core.internal.flow.ClassProbesAdapter; 1672793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmannimport org.jacoco.core.runtime.IExecutionDataAccessorGenerator; 1772793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmannimport org.objectweb.asm.ClassReader; 1872793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmannimport org.objectweb.asm.Opcodes; 1972793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann 2072793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann/** 2172793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann * Factory to find a suitable strategy to access the probe array for a given 2272793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann * class. 2372793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann */ 2472793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmannpublic final class ProbeArrayStrategyFactory { 2572793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann 2672793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann private ProbeArrayStrategyFactory() { 2772793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann } 2872793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann 2972793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann /** 3072793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann * Creates a suitable strategy instance for the class described by the given 3172793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann * reader. 3272793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann * 3372793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann * @param reader 3472793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann * reader to get information about the class 3572793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann * @param accessorGenerator 3672793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann * accessor to the coverage runtime 3772793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann * @return strategy instance 3872793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann */ 3972793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann public static IProbeArrayStrategy createFor(final ClassReader reader, 4072793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann final IExecutionDataAccessorGenerator accessorGenerator) { 4172793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann 4272793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann final String className = reader.getClassName(); 4372793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann final int version = getVersion(reader); 4472793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann final long classId = CRC64.checksum(reader.b); 4572793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann final boolean withFrames = version >= Opcodes.V1_6; 4672793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann 4772793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann if (isInterface(reader)) { 4872793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann final ProbeCounter counter = getProbeCounter(reader); 4972793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann if (counter.getCount() == 0) { 5072793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann return new NoneProbeArrayStrategy(); 5172793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann } 5272793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann if (version >= Opcodes.V1_8 && counter.hasMethods()) { 5372793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann return new FieldProbeArrayStrategy(className, classId, 5472793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann withFrames, InstrSupport.DATAFIELD_INTF_ACC, 5572793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann accessorGenerator); 5672793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann } else { 5772793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann return new LocalProbeArrayStrategy(className, classId, 5872793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann counter.getCount(), accessorGenerator); 5972793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann } 6072793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann } else { 6172793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann return new FieldProbeArrayStrategy(className, classId, withFrames, 6272793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann InstrSupport.DATAFIELD_ACC, accessorGenerator); 6372793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann } 6472793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann } 6572793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann 6672793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann private static boolean isInterface(final ClassReader reader) { 6772793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann return (reader.getAccess() & Opcodes.ACC_INTERFACE) != 0; 6872793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann } 6972793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann 7072793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann private static int getVersion(final ClassReader reader) { 7172793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann return reader.readShort(6); 7272793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann } 7372793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann 7472793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann private static ProbeCounter getProbeCounter(final ClassReader reader) { 7572793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann final ProbeCounter counter = new ProbeCounter(); 7672793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann reader.accept(new ClassProbesAdapter(counter, false), 0); 7772793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann return counter; 7872793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann } 7972793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann 8072793f84314a393b86c5dc344499888b7113d20bMarc R. Hoffmann} 81