001 /* 002 * Sonar, open source software quality management tool. 003 * Copyright (C) 2009 SonarSource SA 004 * mailto:contact AT sonarsource DOT com 005 * 006 * Sonar is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 3 of the License, or (at your option) any later version. 010 * 011 * Sonar is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public 017 * License along with Sonar; if not, write to the Free Software 018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 019 */ 020 package org.sonar.java.bytecode.asm; 021 022 import org.objectweb.asm.Label; 023 import org.objectweb.asm.Opcodes; 024 import org.objectweb.asm.Type; 025 import org.objectweb.asm.commons.EmptyVisitor; 026 import org.sonar.java.bytecode.asm.AsmClassProvider.DETAIL_LEVEL; 027 import org.sonar.squid.api.SourceCodeEdgeUsage; 028 029 public class AsmMethodVisitor extends EmptyVisitor { 030 031 private AsmMethod method; 032 private AsmClassProvider asmClassProvider; 033 private int lineNumber = 0; 034 private boolean emptyMethod = true; 035 036 public AsmMethodVisitor(AsmMethod method, AsmClassProvider asmClassProvider) { 037 this.method = method; 038 this.asmClassProvider = asmClassProvider; 039 emptyMethod = true; 040 } 041 042 public void visitFieldInsn(int opcode, String owner, String fieldName, String fieldDescription) { 043 AsmClass targetClass = asmClassProvider.getClass(owner, DETAIL_LEVEL.NOTHING); 044 AsmField targetField = targetClass.getFieldOrCreateIt(fieldName); 045 method.addEdge(new AsmEdge(method, targetField, SourceCodeEdgeUsage.CALLS_FIELD, lineNumber)); 046 emptyMethod = false; 047 } 048 049 public void visitMethodInsn(int opcode, String owner, String methodName, String methodDescription) { 050 AsmClass targetClass = asmClassProvider.getClass(owner, DETAIL_LEVEL.NOTHING); 051 AsmMethod targetMethod = targetClass.getMethodOrCreateIt(methodName + methodDescription); 052 method.addEdge(new AsmEdge(method, targetMethod, SourceCodeEdgeUsage.CALLS_METHOD, lineNumber)); 053 emptyMethod = false; 054 } 055 056 public void visitTryCatchBlock(Label start, Label end, Label handler, String exception) { 057 if (exception != null) { 058 AsmClass exceptionClass = asmClassProvider.getClass(exception, DETAIL_LEVEL.NOTHING); 059 method.addEdge(new AsmEdge(method, exceptionClass, SourceCodeEdgeUsage.USES, lineNumber)); 060 } 061 emptyMethod = false; 062 } 063 064 public void visitTypeInsn(int opcode, String internalName) { 065 AsmClass usedClass = asmClassProvider.getClass(internalName, DETAIL_LEVEL.NOTHING); 066 method.addEdge(new AsmEdge(method, usedClass, SourceCodeEdgeUsage.USES, lineNumber)); 067 emptyMethod = false; 068 } 069 070 public void visitLineNumber(final int line, final Label start) { 071 lineNumber = line; 072 } 073 074 public void visitEnd() { 075 method.setEmpty(emptyMethod); 076 } 077 078 public void visitIincInsn(int var, int increment) { 079 emptyMethod = false; 080 } 081 082 public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) { 083 emptyMethod = false; 084 } 085 086 public void visitInsn(int opcode) { 087 if (opcode != Opcodes.RETURN) { 088 emptyMethod = false; 089 } 090 } 091 092 public void visitIntInsn(int opcode, int operand) { 093 emptyMethod = false; 094 } 095 096 public void visitJumpInsn(int opcode, Label label) { 097 emptyMethod = false; 098 } 099 100 public void visitLdcInsn(Object cst) { 101 if (cst instanceof Type) { 102 Type type = (Type) cst; 103 AsmClass usedClass = asmClassProvider.getClass(type.getInternalName(), DETAIL_LEVEL.NOTHING); 104 method.addEdge(new AsmEdge(method, usedClass, SourceCodeEdgeUsage.USES, lineNumber)); 105 } 106 emptyMethod = false; 107 } 108 109 public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { 110 emptyMethod = false; 111 } 112 113 public void visitMultiANewArrayInsn(String desc, int dims) { 114 emptyMethod = false; 115 } 116 117 public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) { 118 emptyMethod = false; 119 } 120 121 public void visitVarInsn(int opcode, int var) { 122 emptyMethod = false; 123 } 124 }