package polyglot.ext.jl.ast;
import polyglot.ast.*;
import polyglot.types.*;
import polyglot.visit.*;
import polyglot.util.*;
import java.util.*;
/**
* A <code>ArrayAccessAssign_c</code> represents a Java assignment expression
* to an array element. For instance, <code>A[3] = e</code>.
*
* The class of the <code>Expr</code> returned by
* <code>ArrayAccessAssign_c.left()</code>is guaranteed to be an
* <code>ArrayAccess</code>.
*/
public class ArrayAccessAssign_c extends Assign_c implements ArrayAccessAssign
{
public ArrayAccessAssign_c(Position pos, ArrayAccess left, Operator op, Expr right) {
super(pos, left, op, right);
}
public Assign left(Expr left) {
ArrayAccessAssign_c n = (ArrayAccessAssign_c)super.left(left);
n.assertLeftType();
return n;
}
private void assertLeftType() {
if (!(left() instanceof ArrayAccess)) {
throw new InternalCompilerError("left expression of an ArrayAccessAssign must be an array access");
}
}
public Term entry() {
return left().entry();
}
protected void acceptCFGAssign(CFGBuilder v) {
ArrayAccess a = (ArrayAccess)left();
// a[i] = e: visit a -> i -> e -> (a[i] = e)
v.visitCFG(a.array(), a.index().entry());
v.visitCFG(a.index(), right().entry());
v.visitCFG(right(), this);
}
protected void acceptCFGOpAssign(CFGBuilder v) {
ArrayAccess a = (ArrayAccess)left();
// a[i] OP= e: visit a -> i -> a[i] -> e -> (a[i] OP= e)
v.visitCFG(a.array(), a.index().entry());
v.visitCFG(a.index(), a);
v.visitThrow(a);
v.edge(a, right().entry());
v.visitCFG(right(), this);
}
public List throwTypes(TypeSystem ts) {
List l = new ArrayList(super.throwTypes(ts));
if (throwsArrayStoreException()) {
l.add(ts.ArrayStoreException());
}
l.add(ts.NullPointerException());
l.add(ts.OutOfBoundsException());
return l;
}
/** Get the throwsArrayStoreException of the expression. */
public boolean throwsArrayStoreException() {
return op == ASSIGN && left.type().isReference();
}
}