MethodAnalyzer.java

    1/*******************************************************************************
    2 * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
    3 * All rights reserved. This program and the accompanying materials
    4 * are made available under the terms of the Eclipse Public License v1.0
    5 * which accompanies this distribution, and is available at
    6 * http://www.eclipse.org/legal/epl-v10.html
    7 *
    8 * Contributors:
    9 *    Marc R. Hoffmann - initial API and implementation
   10 *    
   11 * $Id: $
   12 *******************************************************************************/
   13package org.jacoco.core.instr;
   14
   15import org.jacoco.core.data.IMethodStructureVisitor;
   16import org.objectweb.asm.AnnotationVisitor;
   17import org.objectweb.asm.Attribute;
   18import org.objectweb.asm.Label;
   19
   20/**
   21 * This {@link IBlockMethodVisitor} analyzes the block structure of a method and
   22 * reports it to a {@link IMethodStructureVisitor} instance.
   23 * 
   24 * @author Marc R. Hoffmann
   25 * @version $Revision: $
   26 */
   27public final class MethodAnalyzer implements IBlockMethodVisitor {
   28
   29    private static final int NO_LINE_INFO = -1;
   30
   31    private final IMethodStructureVisitor structureVisitor;
   32
   33    private int instructionCount;
   34
   35    private int currentLine;
   36
   37    private final IntSet lineNumbers;
   38
   39    /**
   40     * Creates a new analyzer that reports to the given
   41     * {@link IMethodStructureVisitor} instance.
   42     * 
   43     * @param structureVisitor
   44     *            consumer for method structure events
   45     */
   46    public MethodAnalyzer(final IMethodStructureVisitor structureVisitor) {
   47        this.structureVisitor = structureVisitor;
   48        this.instructionCount = 0;
   49        this.currentLine = NO_LINE_INFO;
   50        this.lineNumbers = new IntSet();
   51    }
   52
   53    private void addInstruction() {
   54        instructionCount++;
   55        if (currentLine != NO_LINE_INFO) {
   56            lineNumbers.add(currentLine);
   57        }
   58    }
   59
   60    // === MethodVisitor ===
   61
   62    public AnnotationVisitor visitAnnotation(final String desc,
   63            final boolean visible) {
   64        return null;
   65    }
   66
   67    public AnnotationVisitor visitAnnotationDefault() {
   68        return null;
   69    }
   70
   71    public AnnotationVisitor visitParameterAnnotation(final int parameter,
   72            final String desc, final boolean visible) {
   73        return null;
   74    }
   75
   76    public void visitAttribute(final Attribute attr) {
   77    }
   78
   79    public void visitCode() {
   80    }
   81
   82    public void visitFrame(final int type, final int local,
   83            final Object[] local2, final int stack, final Object[] stack2) {
   84    }
   85
   86    public void visitLabel(final Label label) {
   87    }
   88
   89    public void visitLocalVariable(final String name, final String desc,
   90            final String signature, final Label start, final Label end,
   91            final int index) {
   92    }
   93
   94    public void visitTryCatchBlock(final Label start, final Label end,
   95            final Label handler, final String type) {
   96    }
   97
   98    public void visitMaxs(final int maxStack, final int maxLocals) {
   99    }
  100
  101    public void visitLineNumber(final int line, final Label start) {
  102        currentLine = line;
  103    }
  104
  105    public void visitInsn(final int opcode) {
  106        addInstruction();
  107    }
  108
  109    public void visitJumpInsn(final int opcode, final Label label) {
  110        addInstruction();
  111    }
  112
  113    public void visitFieldInsn(final int opcode, final String owner,
  114            final String name, final String desc) {
  115        addInstruction();
  116    }
  117
  118    public void visitIincInsn(final int var, final int increment) {
  119        addInstruction();
  120    }
  121
  122    public void visitIntInsn(final int opcode, final int operand) {
  123        addInstruction();
  124    }
  125
  126    public void visitLdcInsn(final Object cst) {
  127        addInstruction();
  128    }
  129
  130    public void visitLookupSwitchInsn(final Label dflt, final int[] keys,
  131            final Label[] labels) {
  132        addInstruction();
  133    }
  134
  135    public void visitMethodInsn(final int opcode, final String owner,
  136            final String name, final String desc) {
  137        addInstruction();
  138    }
  139
  140    public void visitMultiANewArrayInsn(final String desc, final int dims) {
  141        addInstruction();
  142    }
  143
  144    public void visitTableSwitchInsn(final int min, final int max,
  145            final Label dflt, final Label[] labels) {
  146        addInstruction();
  147    }
  148
  149    public void visitTypeInsn(final int opcode, final String type) {
  150        addInstruction();
  151    }
  152
  153    public void visitVarInsn(final int opcode, final int var) {
  154        addInstruction();
  155    }
  156
  157    public void visitEnd() {
  158        structureVisitor.visitEnd();
  159    }
  160
  161    // === IBlockVisitor ===
  162
  163    public void visitBlockEndBeforeJump(final int id) {
  164    }
  165
  166    public void visitBlockEnd(final int id) {
  167        structureVisitor.block(id, instructionCount, lineNumbers.toArray());
  168        instructionCount = 0;
  169        lineNumbers.clear();
  170    }
  171
  172}