org.sonar.java.bytecode.asm.AsmMethodVisitor.java Source code

Java tutorial

Introduction

Here is the source code for org.sonar.java.bytecode.asm.AsmMethodVisitor.java

Source

/*
 * Sonar, open source software quality management tool.
 * Copyright (C) 2008-2011 SonarSource
 * mailto:contact AT sonarsource DOT com
 *
 * Sonar is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * Sonar 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with Sonar; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
 */
package org.sonar.java.bytecode.asm;

import org.objectweb.asm.Label;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.EmptyVisitor;
import org.sonar.java.bytecode.asm.AsmClassProvider.DETAIL_LEVEL;
import org.sonar.squid.api.SourceCodeEdgeUsage;

public class AsmMethodVisitor extends EmptyVisitor {

    private AsmMethod method;
    private AsmClassProvider asmClassProvider;
    private int lineNumber = 0;
    private boolean emptyMethod = true;

    public AsmMethodVisitor(AsmMethod method, AsmClassProvider asmClassProvider) {
        this.method = method;
        this.asmClassProvider = asmClassProvider;
        emptyMethod = true;
    }

    public void visitFieldInsn(int opcode, String owner, String fieldName, String fieldDescription) {
        AsmClass targetClass = asmClassProvider.getClass(owner, DETAIL_LEVEL.NOTHING);
        AsmField targetField = targetClass.getFieldOrCreateIt(fieldName);
        method.addEdge(new AsmEdge(method, targetField, SourceCodeEdgeUsage.CALLS_FIELD, lineNumber));
        emptyMethod = false;
    }

    public void visitMethodInsn(int opcode, String owner, String methodName, String methodDescription) {
        if (isNotCallToJavaArrayMethod(owner)) {
            AsmClass targetClass = asmClassProvider.getClass(owner, DETAIL_LEVEL.STRUCTURE);
            AsmMethod targetMethod = targetClass.getMethodOrCreateIt(methodName + methodDescription);
            method.addEdge(new AsmEdge(method, targetMethod, SourceCodeEdgeUsage.CALLS_METHOD, lineNumber));
        }
        emptyMethod = false;
    }

    private boolean isNotCallToJavaArrayMethod(String internalName) {
        return internalName.charAt(0) != '[';
    }

    public void visitTryCatchBlock(Label start, Label end, Label handler, String exception) {
        if (exception != null) {
            AsmClass exceptionClass = asmClassProvider.getClass(exception, DETAIL_LEVEL.NOTHING);
            method.addEdge(new AsmEdge(method, exceptionClass, SourceCodeEdgeUsage.USES, lineNumber));
        }
        emptyMethod = false;
    }

    public void visitTypeInsn(int opcode, String internalName) {
        AsmClass usedClass = asmClassProvider.getClass(internalName, DETAIL_LEVEL.NOTHING);
        method.addEdge(new AsmEdge(method, usedClass, SourceCodeEdgeUsage.USES, lineNumber));
        emptyMethod = false;
    }

    public void visitLineNumber(final int line, final Label start) {
        lineNumber = line;
    }

    public void visitEnd() {
        method.setEmpty(emptyMethod);
    }

    public void visitIincInsn(int var, int increment) {
        emptyMethod = false;
    }

    public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) {
        emptyMethod = false;
    }

    public void visitInsn(int opcode) {
        if (opcode != Opcodes.RETURN) {
            emptyMethod = false;
        }
    }

    public void visitIntInsn(int opcode, int operand) {
        emptyMethod = false;
    }

    public void visitJumpInsn(int opcode, Label label) {
        emptyMethod = false;
    }

    public void visitLdcInsn(Object cst) {
        if (cst instanceof Type) {
            Type type = (Type) cst;
            AsmClass usedClass = asmClassProvider.getClass(type.getInternalName(), DETAIL_LEVEL.NOTHING);
            method.addEdge(new AsmEdge(method, usedClass, SourceCodeEdgeUsage.USES, lineNumber));
        }
        emptyMethod = false;
    }

    public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
        emptyMethod = false;
    }

    public void visitMultiANewArrayInsn(String desc, int dims) {
        emptyMethod = false;
    }

    public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) {
        emptyMethod = false;
    }

    public void visitVarInsn(int opcode, int var) {
        emptyMethod = false;
    }
}