blob: 7881fcb11704978f6b39736f1630787e880e9d7b [file] [log] [blame]
package org.eclipse.jdi.internal;
/*
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved.
*/
import com.sun.jdi.*;
import com.sun.jdi.connect.*;
import com.sun.jdi.event.*;
import com.sun.jdi.request.*;
import org.eclipse.jdi.internal.connect.*;
import org.eclipse.jdi.internal.request.*;
import org.eclipse.jdi.internal.event.*;
import org.eclipse.jdi.internal.jdwp.*;
import org.eclipse.jdi.internal.spy.*;
import java.util.*;
import java.io.*;
/**
* this class implements the corresponding interfaces
* declared by the JDI specification. See the com.sun.jdi package
* for more information.
*
*/
public class LocalVariableImpl extends MirrorImpl implements LocalVariable {
/** Method that holds local variable. */
private MethodImpl fMethod;
/** First code index at which the variable is visible (unsigned). */
private long fCodeIndex;
/** The variable's name. */
private String fName;
/** The variable type's JNI signature. */
private String fSignature;
/** Unsigned value used in conjunction with codeIndex. The variable can be get or set only when the current codeIndex <= current frame code index < code index + length. */
private int fLength;
/** The local variable's index in its frame. */
private int fSlot;
/** Is the local variable an argument of its method? */
private boolean fIsArgument;
public LocalVariableImpl(VirtualMachineImpl vmImpl, MethodImpl method, long codeIndex, String name, String signature, int length, int slot, boolean isArgument) {
super("LocalVariable", vmImpl);
fMethod = method;
fCodeIndex = codeIndex;
fName = name;
fSignature = signature;
fLength = length;
fSlot = slot;
fIsArgument = isArgument;
}
/**
* @return Returns local variable's index in its frame.
*/
public int slot() {
return fSlot;
}
/**
* @return Returns the hash code value.
*/
public int hashCode() {
return fMethod.hashCode() + (int)fCodeIndex + fSlot;
}
/**
* @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) {
if (object != null && object.getClass().equals(this.getClass())) {
LocalVariableImpl loc = (LocalVariableImpl)object;
return fMethod.equals(loc.fMethod) && fCodeIndex == loc.fCodeIndex && fSlot == loc.fSlot;
}
return false;
}
/**
* @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("Can't compare local variable to given object.");
// See if methods are the same, if not return comparison between methods.
LocalVariableImpl var2 = (LocalVariableImpl)object;
if (!method().equals(var2.method()))
return method().compareTo(var2.method());
// Return comparison between the index of each local variable in its stack frame.
// Code indexes must be treated as unsigned. This matters if you have to compare them.
if (fCodeIndex < 0 || var2.fCodeIndex < 0)
throw new InternalError("Code indexes are assumed to be always positive.");
long index2 = var2.fCodeIndex;
if (fCodeIndex < index2)
return -1;
else if (fCodeIndex > index2)
return 1;
else return 0;
}
/**
* @return Returns true if this variable is an argument to its method.
*/
public boolean isArgument() {
return fIsArgument;
}
public boolean isVisible(StackFrame frame) throws IllegalArgumentException, VMMismatchException {
checkVM(frame);
StackFrameImpl frameImpl = (StackFrameImpl)frame;
if (!fMethod.equals(frameImpl.location().method()))
throw new IllegalArgumentException("The stack frame's method does not match this variable's method.");
long currentIndex = frameImpl.location().codeIndex();
// Code indexes must be treated as unsigned. This matters if you have to compare them.
if (currentIndex >= 0 && fCodeIndex >= 0 && fCodeIndex + fLength >= 0)
return fCodeIndex <= currentIndex && currentIndex < fCodeIndex + fLength;
throw new InternalError("Code indexes are assumed to be always positive.");
}
/**
* @return Returns the name of the local variable.
*/
public String name() {
return fName;
}
/**
* @return Returns the signature of the local variable.
*/
public String signature() {
return fSignature;
}
/**
* @return Returns the type of the this LocalVariable.
*/
public Type type() throws ClassNotLoadedException {
return TypeImpl.create(virtualMachineImpl(), fSignature, method().declaringType().classLoader());
}
/**
* @return Returns a text representation of the declared type of this variable.
*/
public String typeName() {
return TypeImpl.signatureToName(fSignature);
}
/**
* @return Returns the tag of the declared type of this variable.
*/
public byte tag() {
return TypeImpl.signatureToTag(fSignature);
}
/**
* @return Returns the method that holds the local variable.
*/
public MethodImpl method() {
return fMethod;
}
/**
* @return Returns true if the local variable is the 'this' pointer.
*/
public boolean isThis() {
return slot() == 0 && !method().isStatic();
}
/**
* @return Returns description of Mirror object.
*/
public String toString() {
return fName;
}
}