package LBJ2.IR;
import LBJ2.Pass;
/**
* Represents a local variable declaration.
*
* @author Nick Rizzolo
**/
public class VariableDeclaration extends Statement
{
/** Whether or not the argument was modified as final. */
public boolean isFinal;
/** (¬ø) The type of the declared variable. */
public Type type;
/** (¬ø) The names of variables declared in this statement. */
public NameList names;
/**
* (¬ø) The initializing expressions for the declared variables,
* <code>null</code> being an allowable value.
**/
public ExpressionList initializers;
/**
* Parser's constructor, leaving the type to be filled in later.
*
* @param n The name of the declared variable.
**/
public VariableDeclaration(Name n) { this(n, null); }
/**
* Parser's constructor, leaving the type to be filled in later.
*
* @param n The name of the declared variable.
* @param i The initializing expression for the declared variable.
**/
public VariableDeclaration(Name n, Expression i) {
super(-1, -1); // Line and byte offset information will be filled in
// later.
names = new NameList(n);
initializers = new ExpressionList(i);
type = null;
isFinal = false;
}
/**
* Full constructor.
*
* @param t The type of the declared variables.
* @param n The names of the declared variables.
* @param i The initializing expressions for the declared variables.
* @param f Whether or not the variables were declared as final.
**/
public VariableDeclaration(Type t, NameList n, ExpressionList i, boolean f)
{
super(t.line, t.byteOffset);
type = t;
names = n;
initializers = i;
isFinal = f;
}
/**
* Adds the declarations in the specified declaration statement to the
* declarations in this statement.
*
* @param v The variables to be added.
**/
public void addVariables(VariableDeclaration v) {
names.addAll(v.names);
initializers.addAll(v.initializers);
}
/**
* Setting this declaration statement's type also sets its line and byte
* offset information.
*
* @param t The new type for this variable declaration statement.
**/
public void setType(Type t) {
type = t;
line = type.line;
byteOffset = type.byteOffset;
}
/**
* Returns an iterator used to successively access the children of this
* node.
*
* @return An iterator used to successively access the children of this
* node.
**/
public ASTNodeIterator iterator() {
ASTNodeIterator I = new ASTNodeIterator(3);
I.children[0] = type;
I.children[1] = names;
I.children[2] = initializers;
return I;
}
/**
* Creates a new object with the same primitive data, and recursively
* creates new member data objects as well.
*
* @return The clone node.
**/
public Object clone() {
return
new VariableDeclaration((Type) type.clone(), (NameList) names.clone(),
(ExpressionList) initializers.clone(), isFinal);
}
/** Returns a hash code for this {@link ASTNode}. */
public int hashCode() {
return
(isFinal ? 1 : 3) + 7 * type.hashCode() + 17 * names.hashCode()
+ 31 * initializers.hashCode();
}
/**
* Distinguishes this {@link ASTNode} from other objects according to its
* contents recursively.
*
* @param o Another object.
* @return <code>true</code> iff this node is equal to <code>o</code>.
**/
public boolean equals(Object o) {
if (!(o instanceof VariableDeclaration)) return false;
VariableDeclaration v = (VariableDeclaration) o;
return
isFinal == v.isFinal && type.equals(v.type) && names.equals(v.names)
&& initializers.equals(v.initializers);
}
/**
* Ensures that the correct <code>run()</code> method is called for this
* type of node.
*
* @param pass The pass whose <code>run()</code> method should be called.
**/
public void runPass(Pass pass) { pass.run(this); }
/**
* Writes a string representation of this <code>ASTNode</code> to the
* specified buffer. The representation written is parsable by the LBJ2
* compiler, but not very readable.
*
* @param buffer The buffer to write to.
**/
public void write(StringBuffer buffer) {
if (isFinal) buffer.append("final ");
type.write(buffer);
ASTNodeIterator N = names.iterator();
ExpressionList.ExpressionListIterator I = initializers.listIterator();
buffer.append(" ");
N.next().write(buffer);
Expression i = I.nextItem();
if (i != null) {
buffer.append(" = ");
i.write(buffer);
}
while (N.hasNext()) {
buffer.append(", ");
N.next().write(buffer);
i = I.nextItem();
if (i != null) {
buffer.append(" = ");
i.write(buffer);
}
}
buffer.append(";");
}
}