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}