MethodAnalyzer.java

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