package org.jruby.ir.operands;
import org.jruby.RubyArray;
import org.jruby.ir.IRVisitor;
import org.jruby.ir.persistence.IRReaderDecoder;
import org.jruby.ir.persistence.IRWriterEncoder;
import org.jruby.ir.transformations.inlining.CloneInfo;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.DynamicScope;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class Array extends Operand implements Iterable<Operand> {
private final Operand[] elts;
public Array() {
this(EMPTY_ARRAY);
}
public Array(Operand[] elts) {
super();
this.elts = elts == null ? EMPTY_ARRAY : elts;
}
@Override
public OperandType getOperandType() {
return OperandType.ARRAY;
}
public boolean isBlank() {
return elts.length == 0;
}
public int size() {
return elts.length;
}
public Operand get(int i) {
return elts[i];
}
@Override
public String toString() {
return "Array:" + (isBlank() ? "[]" : java.util.Arrays.toString(elts));
}
@Override
public boolean hasKnownValue() {
for (Operand o : elts) {
if (!o.hasKnownValue()) return false;
}
return true;
}
@Override
public Operand getSimplifiedOperand(Map<Operand, Operand> valueMap, boolean force) {
Operand[] newElts = new Operand[elts.length];
for (int i = 0; i < elts.length; i++) {
newElts[i] = elts[i].getSimplifiedOperand(valueMap, force);
}
return new Array(newElts);
}
public Operand toArray() {
return this;
}
@Override
public void addUsedVariables(List<Variable> l) {
for (Operand o: elts) {
o.addUsedVariables(l);
}
}
@Override
public Operand cloneForInlining(CloneInfo ii) {
if (hasKnownValue()) return this;
Operand[] newElts = new Operand[elts.length];
for (int i = 0; i < elts.length; i++) {
newElts[i] = elts[i].cloneForInlining(ii);
}
return new Array(newElts);
}
@Override
public void encode(IRWriterEncoder e) {
super.encode(e);
e.encode(getElts());
}
public static Array decode(IRReaderDecoder d) {
return new Array(d.decodeOperandArray());
}
public IRubyObject[] retrieveArrayElts(ThreadContext context, IRubyObject self, StaticScope currScope, DynamicScope currDynScope, Object[] temp) {
IRubyObject[] elements = new IRubyObject[elts.length];
for (int i = 0; i < elements.length; i++) {
elements[i] = (IRubyObject) elts[i].retrieve(context, self, currScope, currDynScope, temp);
}
return elements;
}
@Override
public Object retrieve(ThreadContext context, IRubyObject self, StaticScope currScope, DynamicScope currDynScope, Object[] temp) {
switch (elts.length) {
case 0:
return context.runtime.newEmptyArray();
case 1:
return context.runtime.newArray((IRubyObject) elts[0].retrieve(context, self, currScope, currDynScope, temp));
case 2:
return context.runtime.newArray((IRubyObject) elts[0].retrieve(context, self, currScope, currDynScope, temp),
(IRubyObject) elts[1].retrieve(context, self, currScope, currDynScope, temp));
default:
return RubyArray.newArrayMayCopy(context.runtime, retrieveArrayElts(context, self, currScope, currDynScope, temp));
}
}
@Override
public void visit(IRVisitor visitor) {
visitor.Array(this);
}
public Operand[] getElts() {
return elts;
}
@Override
public Iterator<Operand> iterator() {
return Arrays.asList(elts).iterator();
}
}