| /********************************************************************** |
| * Copyright (c) 2002, 2005 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Common Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/cpl-v10.html |
| * |
| * Contributors: |
| * IBM - Initial API and implementation |
| **********************************************************************/ |
| |
| package org.eclipse.wtp.releng.tools.component.internal; |
| |
| import java.util.Iterator; |
| import java.util.List; |
| import org.eclipse.jdt.core.util.ByteCodeVisitorAdapter; |
| import org.eclipse.jdt.core.util.IConstantPoolEntry; |
| import org.eclipse.jdt.core.util.ILineNumberAttribute; |
| |
| public class InternalByteCodeVisitor extends ByteCodeVisitorAdapter |
| { |
| private List methodRefs; |
| private List fieldRefs; |
| private ILineNumberAttribute lineNumAttr; |
| private int lineNumIndex; |
| private int nextPC; |
| private int currLine; |
| |
| public InternalByteCodeVisitor(List methodRefs, List fieldRefs, ILineNumberAttribute lineNumAttr) |
| { |
| this.methodRefs = methodRefs; |
| this.fieldRefs = fieldRefs; |
| this.lineNumAttr = lineNumAttr; |
| lineNumIndex = -1; |
| nextPC = -1; |
| currLine = -1; |
| nextLine(); |
| } |
| |
| public void nextLine() |
| { |
| lineNumIndex++; |
| int[][] lineNumTable = lineNumAttr.getLineNumberTable(); |
| if (lineNumIndex < lineNumTable.length) |
| currLine = lineNumTable[lineNumIndex][1]; |
| if (lineNumIndex + 1 < lineNumTable.length) |
| nextPC = lineNumTable[lineNumIndex + 1][0]; |
| else |
| nextPC = -1; |
| } |
| |
| public void _invokeinterface(int pc, int index, byte nargs, IConstantPoolEntry constantInterfaceMethodref) |
| { |
| addMethodRefs(constantInterfaceMethodref, pc); |
| } |
| |
| public void _invokespecial(int pc, int index, IConstantPoolEntry constantMethodref) |
| { |
| addMethodRefs(constantMethodref, pc); |
| } |
| |
| public void _invokestatic(int pc, int index, IConstantPoolEntry constantMethodref) |
| { |
| addMethodRefs(constantMethodref, pc); |
| } |
| |
| public void _invokevirtual(int pc, int index, IConstantPoolEntry constantMethodref) |
| { |
| addMethodRefs(constantMethodref, pc); |
| } |
| |
| public void _getfield(int pc, int index, IConstantPoolEntry constantFieldref) |
| { |
| addFieldRefs(constantFieldref, pc); |
| } |
| |
| public void _getstatic(int pc, int index, IConstantPoolEntry constantFieldref) |
| { |
| addFieldRefs(constantFieldref, pc); |
| } |
| |
| public void _putfield(int pc, int index, IConstantPoolEntry constantFieldref) |
| { |
| addFieldRefs(constantFieldref, pc); |
| } |
| |
| public void _putstatic(int pc, int index, IConstantPoolEntry constantFieldref) |
| { |
| addFieldRefs(constantFieldref, pc); |
| } |
| |
| private void addMethodRefs(IConstantPoolEntry poolEntry, int pc) |
| { |
| while (nextPC != -1 && pc >= nextPC) |
| nextLine(); |
| String className = decodeClassName(new String(poolEntry.getClassName())); |
| String methodName = new String(poolEntry.getMethodName()); |
| String descriptor = new String(poolEntry.getMethodDescriptor()); |
| for (Iterator it = methodRefs.iterator(); it.hasNext();) |
| { |
| MethodRef ref = (MethodRef)it.next(); |
| if (ref.equals(className, methodName, descriptor)) |
| { |
| ref.addLine(currLine); |
| break; |
| } |
| } |
| } |
| |
| private void addFieldRefs(IConstantPoolEntry poolEntry, int pc) |
| { |
| while (nextPC != -1 && pc >= nextPC) |
| nextLine(); |
| String className = decodeClassName(new String(poolEntry.getClassName())); |
| String fieldName = new String(poolEntry.getFieldName()); |
| String descriptor = new String(poolEntry.getFieldDescriptor()); |
| for (Iterator it = fieldRefs.iterator(); it.hasNext();) |
| { |
| FieldRef ref = (FieldRef)it.next(); |
| if (ref.equals(className, fieldName, descriptor)) |
| { |
| ref.addLine(currLine); |
| break; |
| } |
| } |
| } |
| |
| private String decodeClassName(String className) |
| { |
| return className.replace('/', '.'); |
| } |
| } |