/*
 * Cobertura - http://cobertura.sourceforge.net/
 *
 * Copyright (C) 2011 Piotr Tabor
 *
 * Note: This file is dual licensed under the GPL and the Apache
 * Source License (so that it can be used from both the main
 * Cobertura classes and the ant tasks).
 *
 * Cobertura is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation; either version 2 of the License,
 * or (at your option) any later version.
 *
 * Cobertura is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Cobertura; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 */

package net.sourceforge.cobertura.instrument;

import net.sourceforge.cobertura.instrument.pass1.DetectDuplicatedCodeClassVisitor;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.util.CheckClassAdapter;

import java.util.Collection;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;

Class extending ClassVisitor that provides features used by all three passes of instrumentation.
Author:piotr.tabor@gmail.com
/** * Class extending {@link ClassVisitor} that provides features used by all three passes of instrumentation. * * @author piotr.tabor@gmail.com */
public class AbstractFindTouchPointsClassInstrumenter extends ClassVisitor {
List of patterns to know that we don't want trace lines that are calls to some methods
/** * List of patterns to know that we don't want trace lines that are calls to some methods */
private Collection<Pattern> ignoreRegexp;
We assign 'unique event identifiers' to every asm instruction or directive found in the file. Using the identifiers we are able to distinguish if the instruction is the same as found in the other pass of instrumentation.

We will use this 'generator' to provide this identifiers. Remember to acquire identifiers using AtomicInteger.incrementAndGet() (not AtomicInteger.getAndIncrement()!!!)
/** * We assign 'unique event identifiers' to every asm instruction or directive found in the file. Using the identifiers * we are able to distinguish if the instruction is the same as found in the other pass of instrumentation. * <p/> * We will use this 'generator' to provide this identifiers. Remember to acquire identifiers using {@link AtomicInteger#incrementAndGet()} (not {@link AtomicInteger#getAndIncrement()}!!!) */
protected AtomicInteger eventIdGenerator = new AtomicInteger(0);
We need to assign a unique lineId to every found 'LINENUMBER' directive in the asm code.

Remember that there can exist such a scenario:

LINENUMBER 15 L1  //assigned lineId=33
...
LINENUMBER 16 L2  //assigned lineId=34
...
LINENUMBER 15 L3  //assigned lineId=35
This is a reason, why we are going to use this lineIds instead of just 'line number'

We will use this 'generator' to provide this identifiers. Remember to acquire identifiers using AtomicInteger.incrementAndGet() (not AtomicInteger.getAndIncrement()!!!)

The lineIdGenerator that generates the same identifiers is used by: DetectDuplicatedCodeClassVisitor.lineIdGenerator

/** * We need to assign a unique lineId to every found 'LINENUMBER' directive in the asm code. * <p/> * <p>Remember that there can exist such a scenario: * <pre> * LINENUMBER 15 L1 //assigned lineId=33 * ... * LINENUMBER 16 L2 //assigned lineId=34 * ... * LINENUMBER 15 L3 //assigned lineId=35 * </pre> * This is a reason, why we are going to use this lineIds instead of just 'line number' * </p> * <p/> * <p>We will use this 'generator' to provide this identifiers. Remember to acquire identifiers using {@link AtomicInteger#incrementAndGet()} (not {@link AtomicInteger#getAndIncrement()}!!!)</p> * <p/> * <p>The {@link #lineIdGenerator} that generates the same identifiers is used by: {@link DetectDuplicatedCodeClassVisitor#lineIdGenerator}</p> */
protected final AtomicInteger lineIdGenerator = new AtomicInteger(0);

This is a map of found duplicates of line blocks. It's (lineNumber -> (duplicate LineId -> orygin lineId))

The duplicatedLinesMap can be created by a single pass of DetectDuplicatedCodeClassVisitor (read there for reasons of duplicated detection).

The 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).

/** * <p>This is a map of found duplicates of line blocks. It's (lineNumber -> (duplicate LineId -> orygin lineId))</p> * <p/> * <p>The duplicatedLinesMap can be created by a single pass of {@link DetectDuplicatedCodeClassVisitor} (read there for reasons of duplicated detection).</p> * <p/> * <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). */
protected final Map<Integer, Map<Integer, Integer>> duplicatedLinesMap;
Params:
  • cv – - a listener for code-instrumentation events
  • ignoreRegexp – - list of patters of method calls that should be ignored from line-coverage-measurement
  • duplicatedLinesMap – - map of found duplicates in the class. You should use DetectDuplicatedCodeClassVisitor to find the duplicated lines.
/** * @param cv - a listener for code-instrumentation events * @param ignoreRegexp - list of patters of method calls that should be ignored from line-coverage-measurement * @param duplicatedLinesMap - map of found duplicates in the class. You should use {@link DetectDuplicatedCodeClassVisitor} to find the duplicated lines. */
public AbstractFindTouchPointsClassInstrumenter(ClassVisitor cv, Collection<Pattern> ignoreRegexp, Map<Integer, Map<Integer, Integer>> duplicatedLinesMap) { super(Opcodes.ASM4, new CheckClassAdapter(cv, false)); this.ignoreRegexp = ignoreRegexp; this.duplicatedLinesMap = duplicatedLinesMap; }
Gets list of patterns to know that we don't want trace lines that are calls to some methods
/** * Gets list of patterns to know that we don't want trace lines that are calls to some methods */
public Collection<Pattern> getIgnoreRegexp() { return ignoreRegexp; }
Sets list of pattern to know that we don't want trace lines that are calls to some methods
/** * Sets list of pattern to know that we don't want trace lines that are calls to some methods */
public void setIgnoreRegexp(Collection<Pattern> ignoreRegexp) { this.ignoreRegexp = ignoreRegexp; } }