001/* 002 * Cobertura - http://cobertura.sourceforge.net/ 003 * 004 * Copyright (C) 2011 Piotr Tabor 005 * 006 * Note: This file is dual licensed under the GPL and the Apache 007 * Source License (so that it can be used from both the main 008 * Cobertura classes and the ant tasks). 009 * 010 * Cobertura is free software; you can redistribute it and/or modify 011 * it under the terms of the GNU General Public License as published 012 * by the Free Software Foundation; either version 2 of the License, 013 * or (at your option) any later version. 014 * 015 * Cobertura is distributed in the hope that it will be useful, but 016 * WITHOUT ANY WARRANTY; without even the implied warranty of 017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 018 * General Public License for more details. 019 * 020 * You should have received a copy of the GNU General Public License 021 * along with Cobertura; if not, write to the Free Software 022 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 023 * USA 024 */ 025 026package net.sourceforge.cobertura.instrument; 027 028import java.util.Collection; 029import java.util.Map; 030import java.util.concurrent.atomic.AtomicInteger; 031import java.util.regex.Pattern; 032 033import net.sourceforge.cobertura.instrument.pass1.DetectDuplicatedCodeClassVisitor; 034 035import org.objectweb.asm.ClassVisitor; 036import org.objectweb.asm.Opcodes; 037 038 039/** 040 * Class extending {@link ClassAdapter} that provides features used by all three passes of instrumentation. 041 * 042 * @author piotr.tabor@gmail.com 043 */ 044public class AbstractFindTouchPointsClassInstrumenter extends ClassVisitor{ 045 /** 046 * List of patterns to know that we don't want trace lines that are calls to some methods 047 */ 048 private Collection<Pattern> ignoreRegexp; 049 050 /** 051 * We assign 'unique event identifiers' to every asm instruction or directive found in the file. Using the identifiers 052 * we are able to distinguish if the instruction is the same as found in the other pass of instrumentation. 053 * 054 * We will use this 'generator' to provide this identifiers. Remember to acquire identifiers using {@link AtomicInteger#incrementAndGet()} (not {@link AtomicInteger#getAndIncrement()}!!!) 055 */ 056 protected AtomicInteger eventIdGenerator=new AtomicInteger(0); 057 058 /** 059 * We need to assign a unique lineId to every found 'LINENUMBER' directive in the asm code. 060 * 061 * <p>Remember that there can exist such a scenario: 062 * <pre> 063 * LINENUMBER 15 L1 //assigned lineId=33 064 * ... 065 * LINENUMBER 16 L2 //assigned lineId=34 066 * ... 067 * LINENUMBER 15 L3 //assigned lineId=35 068 * </pre> 069 * This is a reason, why we are going to use this lineIds instead of just 'line number' 070 * </p> 071 * 072 * <p>We will use this 'generator' to provide this identifiers. Remember to acquire identifiers using {@link AtomicInteger#incrementAndGet()} (not {@link AtomicInteger#getAndIncrement()}!!!)</p> 073 * 074 * <p>The {@link #lineIdGenerator} that generates the same identifiers is used by: {@link DetectDuplicatedCodeClassVisitor#lineIdGenerator}</p> 075 */ 076 protected final AtomicInteger lineIdGenerator=new AtomicInteger(0); 077 078 /** 079 * <p>This is a map of found duplicates of line blocks. It's (lineNumber -> (duplicate LineId -> orygin lineId))</p> 080 * 081 * <p>The duplicatedLinesMap can be created by a single pass of {@link DetectDuplicatedCodeClassVisitor} (read there for reasons of duplicated detection).</p> 082 * 083 * <p>The {@link #duplicatedLinesMap} is used to generate the same events Id for events that occurs in ASM code as distinc instructions, but are reason of compilation of the same source-code (finally blocks problem). 084 */ 085 protected final Map<Integer, Map<Integer, Integer>> duplicatedLinesMap; 086 087 /** 088 * @param cv - a listener for code-instrumentation events 089 * @param ignoreRegexp - list of patters of method calls that should be ignored from line-coverage-measurement 090 * @param duplicatedLinesMap - map of found duplicates in the class. You should use {@link DetectDuplicatedCodeClassVisitor} to find the duplicated lines. 091 */ 092 public AbstractFindTouchPointsClassInstrumenter(ClassVisitor cv,Collection<Pattern> ignoreRegexp, 093 Map<Integer, Map<Integer, Integer>> duplicatedLinesMap) { 094 super(Opcodes.ASM4, cv); 095 this.ignoreRegexp=ignoreRegexp; 096 this.duplicatedLinesMap=duplicatedLinesMap; 097 } 098 099 100 /** 101 * Gets list of patterns to know that we don't want trace lines that are calls to some methods 102 */ 103 public Collection<Pattern> getIgnoreRegexp() { 104 return ignoreRegexp; 105 } 106 107 /** 108 * Sets list of pattern to know that we don't want trace lines that are calls to some methods 109 */ 110 public void setIgnoreRegexp(Collection<Pattern> ignoreRegexp) { 111 this.ignoreRegexp = ignoreRegexp; 112 } 113 114}