MethodImpl.java :  » IDE-Eclipse » All-Other-packages » org » eclipse » jdi » internal » Java Open Source

Java Open Source » IDE Eclipse » All Other packages 
All Other packages » org » eclipse » jdi » internal » MethodImpl.java
/*******************************************************************************
 * Copyright (c) 2000, 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Tim Tromey - update method signature syntax (bug 31507)
 *******************************************************************************/
package org.eclipse.jdi.internal;


import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import org.eclipse.jdi.internal.jdwp.JdwpCommandPacket;
import org.eclipse.jdi.internal.jdwp.JdwpMethodID;
import org.eclipse.jdi.internal.jdwp.JdwpReplyPacket;

import com.ibm.icu.text.MessageFormat;
import com.sun.jdi.AbsentInformationException;
import com.sun.jdi.ClassLoaderReference;
import com.sun.jdi.ClassNotLoadedException;
import com.sun.jdi.Locatable;
import com.sun.jdi.Location;
import com.sun.jdi.Method;
import com.sun.jdi.Type;


/**
 * Implementation of com.sun.jdi.Method.
 */
public class MethodImpl extends TypeComponentImpl implements Method, Locatable {
  /** InvokeOptions Constants. */
  public static final int INVOKE_SINGLE_THREADED_JDWP = 0x01;
  public static final int INVOKE_NONVIRTUAL_JDWP = 0x02;
  
  /** Map with Strings for flag bits. */
  private static String[] fgInvokeOptions = null;
  
  /** MethodTypeID that corresponds to this reference. */
  private JdwpMethodID fMethodID;
  
  /** The following are the stored results of JDWP calls. */
  private List fVariables = null;
  private long fLowestValidCodeIndex = -1;
  private long fHighestValidCodeIndex = -1;
  private Map fCodeIndexToLine = null;
  private Map fLineToCodeIndexes = null;
  private Map fStratumAllLineLocations = null;
  private int fArgumentSlotsCount = -1;
  private List fArguments = null;
  private List fArgumentTypes = null;
  private List fArgumentTypeNames = null;
  private List fArgumentTypeSignatures = null;
  private byte[] fByteCodes = null;
  private long[] fCodeIndexTable;
  private int[] fJavaStratumLineNumberTable;
  
  private String fReturnTypeName= null;
  
  /**
   * Creates new MethodImpl.
   */
  public MethodImpl(VirtualMachineImpl vmImpl, ReferenceTypeImpl declaringType, JdwpMethodID methodID, String name, String signature, String genericSignature, int modifierBits) {
    super("Method", vmImpl, declaringType, name, signature, genericSignature, modifierBits); //$NON-NLS-1$
    fMethodID = methodID;
  }

  /**
   * Flushes all stored Jdwp results.
   */
  protected void flushStoredJdwpResults() {
    fVariables = null;
    fLowestValidCodeIndex = -1;
    fHighestValidCodeIndex = -1;
    fCodeIndexToLine = null;
    fLineToCodeIndexes = null;
    fStratumAllLineLocations = null;
    fCodeIndexTable= null;
    fJavaStratumLineNumberTable= null;
    fArgumentSlotsCount = -1;
    fArguments = null;
    fArgumentTypes = null;
    fArgumentTypeNames = null;
    fArgumentTypeSignatures = null;
    fByteCodes = null;
  }
  
  /** 
   * @return Returns methodID of method.
   */
  protected JdwpMethodID getMethodID() {
    return fMethodID;
  }
  
  /** 
   * @return Returns map of location to line number.
   */
  protected Map javaStratumCodeIndexToLine() throws AbsentInformationException {
    if (isAbstract()) {
      return Collections.EMPTY_MAP;
    }
    getLineTable();
    return fCodeIndexToLine;
  }
  
  /** 
   * @return Returns map of line number to locations.
   */
  protected List javaStratumLineToCodeIndexes(int line) throws AbsentInformationException {
    if (isAbstract() || isNative()) {
      return null;
    }
    getLineTable();
    
    return (List)fLineToCodeIndexes.get(new Integer(line));
  }
  
  /** 
   * Gets line table from VM.
   */
  private void getLineTable() throws AbsentInformationException {
    if (isObsolete()) {
      return;
    }
    if (fCodeIndexToLine != null) {
      if (fCodeIndexToLine.isEmpty()) {
        throw new AbsentInformationException(JDIMessages.MethodImpl_Got_empty_line_number_table_for_this_method_1); 
      }
      return;
    }

    initJdwpRequest();
    try {
      ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
      DataOutputStream outData = new DataOutputStream(outBytes);
      writeWithReferenceType(this, outData);
  
      JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.M_LINE_TABLE, outBytes);
      switch (replyPacket.errorCode()) {
        case JdwpReplyPacket.ABSENT_INFORMATION:
          throw new AbsentInformationException(JDIMessages.MethodImpl_No_line_number_information_available_2); 
        case JdwpReplyPacket.NATIVE_METHOD:
          throw new AbsentInformationException(JDIMessages.MethodImpl_No_line_number_information_available_2); 
      }
      defaultReplyErrorHandler(replyPacket.errorCode());
      
      DataInputStream replyData = replyPacket.dataInStream();
      fLowestValidCodeIndex = readLong("lowest index", replyData); //$NON-NLS-1$
      fHighestValidCodeIndex = readLong("highest index", replyData); //$NON-NLS-1$
      int nrOfElements = readInt("elements", replyData); //$NON-NLS-1$
      fCodeIndexToLine = new HashMap();
      fLineToCodeIndexes = new HashMap();
      if (nrOfElements == 0) {
        throw new AbsentInformationException(JDIMessages.MethodImpl_Got_empty_line_number_table_for_this_method_3); 
      }
      fCodeIndexTable= new long[nrOfElements];
      fJavaStratumLineNumberTable= new int[nrOfElements];
      for (int i = 0; i < nrOfElements; i++) {
        long lineCodeIndex = readLong("code index", replyData); //$NON-NLS-1$
        Long lineCodeIndexLong = new Long(lineCodeIndex);
        int lineNr = readInt("line nr", replyData); //$NON-NLS-1$
        Integer lineNrInt = new Integer(lineNr);
        
        // Add entry to code-index to line mapping.
        fCodeIndexToLine.put(lineCodeIndexLong, lineNrInt);
        
        fCodeIndexTable[i]= lineCodeIndex;
        fJavaStratumLineNumberTable[i]= lineNr;
        
        List lineNrEntry = (List)fLineToCodeIndexes.get(lineNrInt);
        if (lineNrEntry == null) {
          lineNrEntry= new ArrayList();
          fLineToCodeIndexes.put(lineNrInt, lineNrEntry);
        }
        lineNrEntry.add(lineCodeIndexLong);
      }
    } catch (IOException e) {
      fCodeIndexToLine = null;
      fLineToCodeIndexes = null;
      defaultIOExceptionHandler(e);
    } finally {
      handledJdwpRequest();
    }
  }  
  
  /** 
   * @return Returns the line number that corresponds to the given lineCodeIndex.
   */
  protected int javaStratumLineNumber(long lineCodeIndex) throws AbsentInformationException {
    if (isAbstract() || isNative() || isObsolete()) {
      return -1;
    }
    getLineTable();
    if (lineCodeIndex > fHighestValidCodeIndex) {
            throw new AbsentInformationException(JDIMessages.MethodImpl_Invalid_code_index_of_a_location_given_4); 
    }

    Long lineCodeIndexObj;
    Integer lineNrObj;
    long index= lineCodeIndex;
    // Search for the line where this code index is located.
    do {
      lineCodeIndexObj = new Long(index);
      lineNrObj = (Integer)javaStratumCodeIndexToLine().get(lineCodeIndexObj);
    } while (lineNrObj == null && --index >= fLowestValidCodeIndex);
    if (lineNrObj == null) {
      if (lineCodeIndex >= fLowestValidCodeIndex) {
        index= lineCodeIndex;
        do {
          lineCodeIndexObj = new Long(index);
          lineNrObj = (Integer)javaStratumCodeIndexToLine().get(lineCodeIndexObj);
        } while (lineNrObj == null && ++index <= fHighestValidCodeIndex);
        if (lineNrObj != null) {
          return lineNrObj.intValue();
        }
      }
      throw new AbsentInformationException (JDIMessages.MethodImpl_Invalid_code_index_of_a_location_given_4); 
    }
    return lineNrObj.intValue();
  }

  
  /**
   * @see com.sun.jdi.Method#allLineLocations()
   */
  public List allLineLocations() throws AbsentInformationException {
    return allLineLocations(virtualMachine().getDefaultStratum(), null);
  }
  
  /**
   * @see com.sun.jdi.Method#arguments()
   */
  public List arguments() throws AbsentInformationException {
    if (isNative() || isAbstract()) {
      throw new AbsentInformationException(JDIMessages.MethodImpl_No_local_variable_information_available_9); 
    }
    if (fArguments != null) {
      return fArguments;
    }
    
    List result = new ArrayList();  
    Iterator iter = variables().iterator();
    while (iter.hasNext()) {
      LocalVariableImpl var = (LocalVariableImpl)iter.next();
      if (var.isArgument())
        result.add(var);
    }
    fArguments = result;
    return fArguments;
  }
  
  /** 
   * @return Returns a text representation of all declared argument types of this method. 
   */
  public List argumentTypeNames() {
    if (fArgumentTypeNames != null) {
      return fArgumentTypeNames;
    }
    List argumentTypeSignatures= argumentTypeSignatures();
    List result= new ArrayList();
    for (Iterator iter= argumentTypeSignatures.iterator(); iter.hasNext();) {
      result.add(TypeImpl.signatureToName((String) iter.next()));
    }
    
    fArgumentTypeNames= result;
    return fArgumentTypeNames;
  }


  /** 
   * @return Returns a signatures of all declared argument types of this method. 
   */
  private List argumentTypeSignatures() {
    if (fArgumentTypeSignatures != null) {
      return fArgumentTypeSignatures;
    }
    
    fArgumentTypeSignatures= GenericSignature.getParameterTypes(signature());
    return fArgumentTypeSignatures;
  }

  /** 
   * @return Returns the list containing the type of each argument. 
   */
  public List argumentTypes() throws ClassNotLoadedException {
    if (fArgumentTypes != null) {
      return fArgumentTypes;
    }

    List result = new ArrayList();
    Iterator iter = argumentTypeSignatures().iterator();
    ClassLoaderReference classLoaderRef= declaringType().classLoader();
    VirtualMachineImpl vm= virtualMachineImpl();
    while (iter.hasNext()) {
      String argumentTypeSignature = (String)iter.next();
      result.add(TypeImpl.create(vm, argumentTypeSignature, classLoaderRef));
    }
    fArgumentTypes = result;
    return fArgumentTypes;
  }

  /** 
   * @return Returns an array containing the bytecodes for this method. 
   */
  public byte[] bytecodes() {
    if (fByteCodes != null) {
      return fByteCodes;
    }

    initJdwpRequest();
    try {
      ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
      DataOutputStream outData = new DataOutputStream(outBytes);
      writeWithReferenceType(this, outData);
      
      JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.M_BYTECODES, outBytes);
      defaultReplyErrorHandler(replyPacket.errorCode());
      
      DataInputStream replyData = replyPacket.dataInStream();
      int length = readInt("length", replyData); //$NON-NLS-1$
      fByteCodes = readByteArray(length, "bytecodes", replyData); //$NON-NLS-1$
      return fByteCodes;
    } catch (IOException e) {
      fByteCodes = null;
      defaultIOExceptionHandler(e);
      return null;
    } finally {
      handledJdwpRequest();
    }
  }

  /** 
   * @return Returns the hash code value.
   */
  public int hashCode() {
    return fMethodID.hashCode();
  }
  
  /**
   * @return Returns true if two mirrors refer to the same entity in the target VM.
   * @see java.lang.Object#equals(Object)
   */
  public boolean equals(Object object) {
    return object != null
      && object.getClass().equals(this.getClass())
      && fMethodID.equals(((MethodImpl)object).fMethodID)
      && referenceTypeImpl().equals(((MethodImpl)object).referenceTypeImpl());
  }

  /**
   * @return Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
   */
  public int compareTo(Object object) {
    if (object == null || !object.getClass().equals(this.getClass()))
      throw new ClassCastException(JDIMessages.MethodImpl_Can__t_compare_method_to_given_object_6); 
    
    // See if declaring types are the same, if not return comparison between declaring types.
    Method type2 = (Method)object;
    if (!declaringType().equals(type2.declaringType()))
      return declaringType().compareTo(type2.declaringType());
    
    // Return comparison of position within declaring type.
    int index1 = declaringType().methods().indexOf(this);
    int index2 = type2.declaringType().methods().indexOf(type2);
    if (index1 < index2) {
      return -1;
    } else if (index1 > index2) {
      return 1;
    } else {
      return 0;
    }
  }
  
  
  /**
   * @see com.sun.jdi.Method#isAbstract()
   */
  public boolean isAbstract() {
    return (fModifierBits & MODIFIER_ACC_ABSTRACT) != 0;
  }
  
  
  /**
   * @see com.sun.jdi.Method#isConstructor()
   */
  public boolean isConstructor() {
    return name().equals("<init>"); //$NON-NLS-1$
  }
  
  /**
   * @see com.sun.jdi.Method#isNative()
   */
  public boolean isNative() {
    return (fModifierBits & MODIFIER_ACC_NATIVE) != 0;
  }
    
  /**
   * @see com.sun.jdi.Method#isStaticInitializer()
   */
  public boolean isStaticInitializer() {
    return name().equals("<clinit>"); //$NON-NLS-1$
  }
  
  /**
   * @see com.sun.jdi.Method#isSynchronized()
   */
  public boolean isSynchronized() {
    return (fModifierBits & MODIFIER_ACC_SYNCHRONIZED) != 0;
  }
  
  /**
   * @see com.sun.jdi.Method#locationOfCodeIndex(long)
   */
  public Location locationOfCodeIndex(long index) {
    if (isAbstract() || isNative()) {
      return null;
    }
    try {
      Integer lineNrInt = (Integer)javaStratumCodeIndexToLine().get(new Long(index));
      if (lineNrInt == null) {
        throw new AbsentInformationException(MessageFormat.format(JDIMessages.MethodImpl_No_valid_location_at_the_specified_code_index__0__2, new Object[]{Long.toString(index)})); 
      }
    } catch (AbsentInformationException e ) {
    }
    return new LocationImpl(virtualMachineImpl(), this, index);
  }
  
  /**
   * @see com.sun.jdi.Method#locationsOfLine(int)
   */
  public List locationsOfLine(int line) throws AbsentInformationException {
    return locationsOfLine(virtualMachine().getDefaultStratum(), null, line);
  }
  
  /**
   * @see com.sun.jdi.Method#returnType()
   */
  public Type returnType() throws ClassNotLoadedException {
    int startIndex = signature().lastIndexOf(')') + 1;  // Signature position is just after ending brace.
    return TypeImpl.create(virtualMachineImpl(), signature().substring(startIndex), declaringType().classLoader());
  }

  
  /**
   * @see com.sun.jdi.Method#returnTypeName()
   */
  public String returnTypeName() {
    if (fReturnTypeName != null) {
      return fReturnTypeName;
    }
    int startIndex = signature().lastIndexOf(')') + 1;  // Signature position is just after ending brace.
    fReturnTypeName= TypeImpl.signatureToName(signature().substring(startIndex));
    return fReturnTypeName;
  }  
  
  
  /**
   * @see com.sun.jdi.Method#variables()
   */
  public List variables() throws AbsentInformationException {
    if (isNative() || isAbstract()) {
      throw new AbsentInformationException(JDIMessages.MethodImpl_No_local_variable_information_available_9); 
    }
    
    if (fVariables != null) {
      return fVariables;
    }

    initJdwpRequest();
    try {
      ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
      DataOutputStream outData = new DataOutputStream(outBytes);
      writeWithReferenceType(this, outData);
      
      boolean withGenericSignature= virtualMachineImpl().isJdwpVersionGreaterOrEqual(1, 5);
      int jdwpCommand= withGenericSignature ? JdwpCommandPacket.M_VARIABLE_TABLE_WITH_GENERIC : JdwpCommandPacket.M_VARIABLE_TABLE;
      JdwpReplyPacket replyPacket = requestVM(jdwpCommand, outBytes);
      switch (replyPacket.errorCode()) {
        case JdwpReplyPacket.ABSENT_INFORMATION:
          return inferArguments();
      }
      
      defaultReplyErrorHandler(replyPacket.errorCode());
      
      DataInputStream replyData = replyPacket.dataInStream();
      fArgumentSlotsCount = readInt("arg count", replyData); //$NON-NLS-1$
      int nrOfElements = readInt("elements", replyData); //$NON-NLS-1$
      List variables = new ArrayList(nrOfElements);
      for (int i = 0; i < nrOfElements; i++) {
        long codeIndex = readLong("code index", replyData); //$NON-NLS-1$
        String name = readString("name", replyData); //$NON-NLS-1$
        String signature = readString("signature", replyData); //$NON-NLS-1$
        String genericSignature= null;
        if (withGenericSignature) {
          genericSignature= readString("generic signature", replyData); //$NON-NLS-1$
          if ("".equals(genericSignature)) { //$NON-NLS-1$
            genericSignature= null;
          }
        }
        int length = readInt("length", replyData); //$NON-NLS-1$
        int slot = readInt("slot", replyData); //$NON-NLS-1$
        boolean isArgument = slot < fArgumentSlotsCount;

        // Note that for instance methods, the first slot contains the this reference.
        if (isStatic() || slot > 0) {
          LocalVariableImpl localVar = new LocalVariableImpl(virtualMachineImpl(), this, codeIndex, name, signature, genericSignature, length, slot, isArgument);
          variables.add(localVar);
        }
      }
      fVariables= variables;
      return fVariables;
    } catch (IOException e) {
      fArgumentSlotsCount = -1;
      fVariables = null;
      defaultIOExceptionHandler(e);
      return null;
    } finally {
      handledJdwpRequest();
    }
  }
  
  
  /**
   * @throws AbsentInformationException
   */
  private List inferArguments() throws AbsentInformationException {
    // infer arguments, if possible
    
    // try to generate the right generic signature for each argument
    String genericSignature= genericSignature();
    String[] signatures= (String[]) argumentTypeSignatures().toArray(new String[0]);
    String[] genericSignatures;
    if (genericSignature == null) {
      genericSignatures= new String[signatures.length];
    } else {
      genericSignatures= (String[]) GenericSignature.getParameterTypes(genericSignature).toArray(new String[0]);
      for (int i= 0; i < genericSignatures.length; i++) {
        if (genericSignatures[i].equals(signatures[i])) {
          genericSignatures[i]= null;
        }
      }
    }
    
    int slot = 0;
    if (!isStatic()) {
      slot++;
    }
    if (signatures.length >0) {
      fArgumentSlotsCount = signatures.length;
      fVariables = new ArrayList(fArgumentSlotsCount);
      for (int i = 0; i < signatures.length; i++) {
        String name = "arg" + i; //$NON-NLS-1$
        LocalVariableImpl localVar = new LocalVariableImpl(virtualMachineImpl(), this, 0, name, signatures[i], genericSignatures[i], -1, slot, true);
        fVariables.add(localVar);
        slot++;
      }
      return fVariables;
    }
    throw new AbsentInformationException(JDIMessages.MethodImpl_No_local_variable_information_available_9); 

  }

  /**
   * @see com.sun.jdi.Method#variablesByName(String)
   */
  public List variablesByName(String name) throws AbsentInformationException {
    Iterator iter = variables().iterator();
    List result = new ArrayList();
    while (iter.hasNext()) {
      LocalVariableImpl var = (LocalVariableImpl)iter.next();
      if (var.name().equals(name)) {
        result.add(var);
      }
    }
    return result;
  }

  /**
   * @see com.sun.jdi.Locatable#location()
   */
  public Location location() {
    if (isAbstract()) {
      return null;
    }
    if (isNative()) {
      return new LocationImpl(virtualMachineImpl(), this, -1);
    }
    // First retrieve line code table.
       try {
      getLineTable();
    } catch (AbsentInformationException e) {
      return new LocationImpl(virtualMachineImpl(), this, -1);
    }

    // Return location with Lowest Valid Code Index.
    return new LocationImpl(virtualMachineImpl(), this, fLowestValidCodeIndex);
  }
  
  /**
   * Writes JDWP representation.
   */
  public void write(MirrorImpl target, DataOutputStream out) throws IOException {
    fMethodID.write(out);
    if (target.fVerboseWriter != null) {
      target.fVerboseWriter.println("method", fMethodID.value()); //$NON-NLS-1$
    }
  }
  
  /**
   * Writes JDWP representation, including ReferenceType.
   */
  protected void writeWithReferenceType(MirrorImpl target, DataOutputStream out) throws IOException {
    referenceTypeImpl().write(target, out);
    write(target, out);
  }

  /**
   * Writes JDWP representation, including ReferenceType with Tag.
   */
  protected void writeWithReferenceTypeWithTag(MirrorImpl target, DataOutputStream out) throws IOException {
    referenceTypeImpl().writeWithTag(target, out);
    write(target, out);
  }

  /**
   * @return Reads JDWP representation and returns new instance.
   */
  protected static MethodImpl readWithReferenceTypeWithTag(MirrorImpl target, DataInputStream in) throws IOException {
    VirtualMachineImpl vmImpl = target.virtualMachineImpl();
      // See Location.
    ReferenceTypeImpl referenceType = ReferenceTypeImpl.readWithTypeTag(target, in);
    if (referenceType == null)
      return null;

    JdwpMethodID ID = new JdwpMethodID(vmImpl);
    if (target.fVerboseWriter != null) {
      target.fVerboseWriter.println("method", ID.value()); //$NON-NLS-1$
    }

    ID.read(in);
    if (ID.isNull()) {
      return null;
    }
      
    // The method must be part of a known reference type.
    MethodImpl method = referenceType.findMethod(ID);
    if (method == null) {
      throw new InternalError(JDIMessages.MethodImpl_Got_MethodID_of_ReferenceType_that_is_not_a_member_of_the_ReferenceType_10); 
    }
    return method;
  }
  
  /**
   * @return Reads JDWP representation and returns new instance.
   */
  protected static MethodImpl readWithNameSignatureModifiers(ReferenceTypeImpl target, ReferenceTypeImpl referenceType, boolean withGenericSignature, DataInputStream in)  throws IOException {
    VirtualMachineImpl vmImpl = target.virtualMachineImpl();
    JdwpMethodID ID = new JdwpMethodID(vmImpl);
    ID.read(in);
    if (target.fVerboseWriter != null) {
      target.fVerboseWriter.println("method", ID.value()); //$NON-NLS-1$
    }

    if (ID.isNull()) {
      return null;
    }
    String name = target.readString("name", in); //$NON-NLS-1$
    String signature = target.readString("signature", in); //$NON-NLS-1$
    String genericSignature= null;
    if (withGenericSignature) {
      genericSignature= target.readString("generic signature", in); //$NON-NLS-1$
      if ("".equals(genericSignature)) { //$NON-NLS-1$
        genericSignature= null;
      }
    }
    int modifierBits= target.readInt("modifiers", AccessibleImpl.getModifierStrings(), in); //$NON-NLS-1$

    MethodImpl mirror = new MethodImpl(vmImpl, referenceType, ID, name, signature, genericSignature, modifierBits);
    return mirror;
  }

  /**
   * Retrieves constant mappings.
   */
  public static void getConstantMaps() {
    if (fgInvokeOptions != null) {
      return;
    }
    
    Field[] fields = MethodImpl.class.getDeclaredFields();
    fgInvokeOptions = new String[32];

    for (int i = 0; i < fields.length; i++) {
      Field field = fields[i];
      if ((field.getModifiers() & Modifier.PUBLIC) == 0 || (field.getModifiers() & java.lang.reflect.Modifier.STATIC) == 0 || (field.getModifiers() & Modifier.FINAL) == 0) {
        continue;
      }
        
      try {
        String name = field.getName();

        if (name.startsWith("INVOKE_")) { //$NON-NLS-1$
          int value = field.getInt(null);
          for (int j = 0; j < fgInvokeOptions.length; j++) {
            if ((1 << j & value) != 0) {
              fgInvokeOptions[j]= name;
              break;
            }
          }
        }
      } catch (IllegalAccessException e) {
        // Will not occur for own class.
      } catch (IllegalArgumentException e) {
        // Should not occur.
        // We should take care that all public static final constants
        // in this class are numbers that are convertible to int.
      }
    }
  }
  
  /**
   * @return Returns a map with string representations of tags.
   */
   protected static String[] getInvokeOptions() {
     getConstantMaps();
     return fgInvokeOptions;
   }
  /**
   * @see Method#isObsolete()
   * 
   * The JDK 1.4.0 specification states that obsolete methods
   * are given an ID of zero. It also states that when a method
   * is redefined, the new method gets the ID of the old method.
   * Thus, the JDWP query for isObsolete on JDK 1.4 will never return true
   * for a non-zero method ID. The query is therefore not needed
   */
  public boolean isObsolete() {
    if (virtualMachineImpl().isJdwpVersionGreaterOrEqual(1, 4)) {
      return fMethodID.value() == 0;
    }
    return false;
  }

  /**
   * @see Method#allLineLocations(String, String)
   */
  public List allLineLocations(String stratum, String sourceName) throws AbsentInformationException {
    if (isAbstract() || isNative()) {
      return Collections.EMPTY_LIST;
    }
    if (stratum == null) { // if stratum not defined use the default stratum for the declaring type
      stratum= declaringType().defaultStratum();
    }
    List allLineLocations= null;
    Map sourceNameAllLineLocations= null;
    if (fStratumAllLineLocations == null) { // the stratum map doesn't exist, create it
      fStratumAllLineLocations= new HashMap();
    } else {
      // get the source name map
      sourceNameAllLineLocations= (Map)fStratumAllLineLocations.get(stratum);
    }
    if (sourceNameAllLineLocations == null) { // the source name map doesn't exist, create it
      sourceNameAllLineLocations= new HashMap();
      fStratumAllLineLocations.put(stratum, sourceNameAllLineLocations);
    } else {
      // get the line locations
      allLineLocations= (List)sourceNameAllLineLocations.get(sourceName);
    }
    if (allLineLocations == null) { // the line locations are not know, compute and store them
      getLineTable();
      allLineLocations= referenceTypeImpl().allLineLocations(stratum, sourceName, this, fCodeIndexTable, fJavaStratumLineNumberTable);
      sourceNameAllLineLocations.put(sourceName, allLineLocations);
    }
    return allLineLocations;
  }

  /**
   * @see Method#locationsOfLine(String, String, int)
   */
  public List locationsOfLine(String stratum, String sourceName, int lineNumber) throws AbsentInformationException {
    if (isAbstract() || isNative()) {
      return Collections.EMPTY_LIST;
    }
    return referenceTypeImpl().locationsOfLine(stratum, sourceName, lineNumber, this);
  }

  /**
   * Return a list which contains a location for the each disjoin range of code indice
   * that have bean assigned to the given lines (by the compiler or/and the VM).
   * Return an empty list if there is not executable code at the specified lines.
   */
  protected List javaStratumLocationsOfLines(List javaLines) throws AbsentInformationException {
    Set  tmpLocations= new TreeSet();
    for (Iterator iter = javaLines.iterator(); iter.hasNext();) {
      Integer key = (Integer)iter.next();
      List indexes= javaStratumLineToCodeIndexes(key.intValue());
      if (indexes != null) {
        tmpLocations.addAll(indexes);
      }
    }
    List locations = new ArrayList();
    for (Iterator iter = tmpLocations.iterator(); iter.hasNext();) {
      long index = ((Long)iter.next()).longValue();
      int position= Arrays.binarySearch(fCodeIndexTable, index);
      if (position == 0 || !tmpLocations.contains(new Long(fCodeIndexTable[position - 1]))) {
        locations.add(new LocationImpl(virtualMachineImpl(), this, index));
      }
    }
    return locations;
  }
  
  public boolean isBridge() {
    return (fModifierBits & MODIFIER_ACC_BRIDGE) != 0;
  }

  public boolean isVarArgs() {
    // TODO: remove this test when j9 solve its problem
    // it returns invalid 1.5 flags for 1.4 classes.
    // see bug 53870
    return !virtualMachine().name().equals("j9") && (fModifierBits & MODIFIER_ACC_VARARGS) != 0; //$NON-NLS-1$
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.