jaxp/src/com/sun/org/apache/bcel/internal/generic/LocalVariableGen.java
Print this page
*** 58,67 ****
--- 58,68 ----
* <http://www.apache.org/>.
*/
import com.sun.org.apache.bcel.internal.Constants;
import com.sun.org.apache.bcel.internal.classfile.*;
+ import com.sun.org.apache.bcel.internal.util.Objects;
/**
* This class represents a local variable within a method. It contains its
* scope, name and type. The generated LocalVariable object can be obtained
* with getLocalVariable which needs the instruction list and the constant
*** 73,83 ****
*/
public class LocalVariableGen
implements InstructionTargeter, NamedAndTyped, Cloneable,
java.io.Serializable
{
! private int index;
private String name;
private Type type;
private InstructionHandle start, end;
/**
--- 74,84 ----
*/
public class LocalVariableGen
implements InstructionTargeter, NamedAndTyped, Cloneable,
java.io.Serializable
{
! private final int index;
private String name;
private Type type;
private InstructionHandle start, end;
/**
*** 129,162 ****
return new LocalVariable(start_pc, length, name_index,
signature_index, index, cp.getConstantPool());
}
- public void setIndex(int index) { this.index = index; }
public int getIndex() { return index; }
public void setName(String name) { this.name = name; }
public String getName() { return name; }
public void setType(Type type) { this.type = type; }
public Type getType() { return type; }
public InstructionHandle getStart() { return start; }
public InstructionHandle getEnd() { return end; }
! public void setStart(InstructionHandle start) {
! BranchInstruction.notifyTarget(this.start, start, this);
this.start = start;
}
! public void setEnd(InstructionHandle end) {
! BranchInstruction.notifyTarget(this.end, end, this);
this.end = end;
}
/**
* @param old_ih old target, either start or end
* @param new_ih new target
*/
public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) {
boolean targeted = false;
if(start == old_ih) {
targeted = true;
--- 130,229 ----
return new LocalVariable(start_pc, length, name_index,
signature_index, index, cp.getConstantPool());
}
public int getIndex() { return index; }
+ @Override
public void setName(String name) { this.name = name; }
+ @Override
public String getName() { return name; }
+ @Override
public void setType(Type type) { this.type = type; }
+ @Override
public Type getType() { return type; }
public InstructionHandle getStart() { return start; }
public InstructionHandle getEnd() { return end; }
! /**
! * Remove this from any known HashSet in which it might be registered.
! */
! void notifyTargetChanging() {
! // hashCode depends on 'index', 'start', and 'end'.
! // Therefore before changing any of these values we
! // need to unregister 'this' from any HashSet where
! // this is registered, and then we need to add it
! // back...
!
! // Unregister 'this' from the HashSet held by 'start'.
! BranchInstruction.notifyTargetChanging(this.start, this);
! if (this.end != this.start) {
! // Since hashCode() is going to change we need to unregister
! // 'this' both form 'start' and 'end'.
! // Unregister 'this' from the HashSet held by 'end'.
! BranchInstruction.notifyTargetChanging(this.end, this);
! }
! }
!
! /**
! * Add back 'this' in all HashSet in which it should be registered.
! **/
! void notifyTargetChanged() {
! // hashCode depends on 'index', 'start', and 'end'.
! // Therefore before changing any of these values we
! // need to unregister 'this' from any HashSet where
! // this is registered, and then we need to add it
! // back...
!
! // Register 'this' in the HashSet held by start.
! BranchInstruction.notifyTargetChanged(this.start, this);
! if (this.end != this.start) {
! // Since hashCode() has changed we need to register
! // 'this' again in 'end'.
! // Add back 'this' in the HashSet held by 'end'.
! BranchInstruction.notifyTargetChanged(this.end, this);
! }
! }
!
! public final void setStart(InstructionHandle start) {
!
! // Call notifyTargetChanging *before* modifying this,
! // as the code triggered by notifyTargetChanging
! // depends on this pointing to the 'old' start.
! notifyTargetChanging();
!
this.start = start;
+
+ // call notifyTargetChanged *after* modifying this,
+ // as the code triggered by notifyTargetChanged
+ // depends on this pointing to the 'new' start.
+ notifyTargetChanged();
}
! public final void setEnd(InstructionHandle end) {
! // call notifyTargetChanging *before* modifying this,
! // as the code triggered by notifyTargetChanging
! // depends on this pointing to the 'old' end.
! // Unregister 'this' from the HashSet held by the 'old' end.
! notifyTargetChanging();
!
this.end = end;
+
+ // call notifyTargetChanged *after* modifying this,
+ // as the code triggered by notifyTargetChanged
+ // depends on this pointing to the 'new' end.
+ // Register 'this' in the HashSet held by the 'new' end.
+ notifyTargetChanged();
+
}
/**
* @param old_ih old target, either start or end
* @param new_ih new target
*/
+ @Override
public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) {
boolean targeted = false;
if(start == old_ih) {
targeted = true;
*** 174,203 ****
}
/**
* @return true, if ih is target of this variable
*/
public boolean containsTarget(InstructionHandle ih) {
return (start == ih) || (end == ih);
}
/**
! * We consider to local variables to be equal, if the use the same index and
* are valid in the same range.
*/
public boolean equals(Object o) {
if(!(o instanceof LocalVariableGen))
return false;
LocalVariableGen l = (LocalVariableGen)o;
return (l.index == index) && (l.start == start) && (l.end == end);
}
public String toString() {
return "LocalVariableGen(" + name + ", " + type + ", " + start + ", " + end + ")";
}
public Object clone() {
try {
return super.clone();
} catch(CloneNotSupportedException e) {
System.err.println(e);
--- 241,286 ----
}
/**
* @return true, if ih is target of this variable
*/
+ @Override
public boolean containsTarget(InstructionHandle ih) {
return (start == ih) || (end == ih);
}
/**
! * We consider two local variables to be equal, if they use the same index and
* are valid in the same range.
*/
+ @Override
public boolean equals(Object o) {
+ if (o==this)
+ return true;
+
if(!(o instanceof LocalVariableGen))
return false;
LocalVariableGen l = (LocalVariableGen)o;
return (l.index == index) && (l.start == start) && (l.end == end);
}
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 59 * hash + this.index;
+ hash = 59 * hash + Objects.hashCode(this.start);
+ hash = 59 * hash + Objects.hashCode(this.end);
+ return hash;
+ }
+
+ @Override
public String toString() {
return "LocalVariableGen(" + name + ", " + type + ", " + start + ", " + end + ")";
}
+ @Override
public Object clone() {
try {
return super.clone();
} catch(CloneNotSupportedException e) {
System.err.println(e);