String elementVarName = elementVar.getName();
JDeclarationStatement elementDecl = (JDeclarationStatement) processStatement(x.elementVariable);
assert (elementDecl.initializer == null);
JForStatement result;
if (x.collectionVariable != null) {
/**
* <pre>
* for (final T[] i$array = collection,
* int i$index = 0,
* final int i$max = i$array.length;
* i$index < i$max; ++i$index) {
* T elementVar = i$array[i$index];
* // user action
* }
* </pre>
*/
JLocal arrayVar = JProgram.createLocal(info, elementVarName + "$array",
((JType) typeMap.get(x.collection.resolvedType)), true,
currentMethodBody);
JLocal indexVar = JProgram.createLocal(info, elementVarName + "$index",
program.getTypePrimitiveInt(), false, currentMethodBody);
JLocal maxVar = JProgram.createLocal(info, elementVarName + "$max",
program.getTypePrimitiveInt(), true, currentMethodBody);
List<JStatement> initializers = new ArrayList<JStatement>(3);
// T[] i$array = arr
initializers.add(createDeclaration(info, arrayVar,
dispProcessExpression(x.collection)));
// int i$index = 0
initializers.add(createDeclaration(info, indexVar,
program.getLiteralInt(0)));
// int i$max = i$array.length
initializers.add(createDeclaration(info, maxVar, new JArrayLength(info,
new JLocalRef(info, arrayVar))));
// i$index < i$max
JExpression condition = new JBinaryOperation(info,
program.getTypePrimitiveBoolean(), JBinaryOperator.LT,
createVariableRef(info, indexVar), createVariableRef(info, maxVar));
// ++i$index
List<JExpressionStatement> increments = new ArrayList<JExpressionStatement>(
1);
increments.add(new JPrefixOperation(info, JUnaryOperator.INC,
createVariableRef(info, indexVar)).makeStatement());
// T elementVar = i$array[i$index];
elementDecl.initializer = new JArrayRef(info, createVariableRef(info,
arrayVar), createVariableRef(info, indexVar));
body.addStmt(0, elementDecl);
result = new JForStatement(info, initializers, condition, increments,
body);
} else {
/**
* <pre>
* for (Iterator<T> i$iterator = collection.iterator(); i$iterator.hasNext();) {
* T elementVar = i$iterator.next();
* // user action
* }
* </pre>
*/
JLocal iteratorVar = JProgram.createLocal(info,
(elementVarName + "$iterator"), program.getIndexedType("Iterator"),
false, currentMethodBody);
List<JStatement> initializers = new ArrayList<JStatement>(1);
// Iterator<T> i$iterator = collection.iterator()
initializers.add(createDeclaration(
info,
iteratorVar,
new JMethodCall(info, dispProcessExpression(x.collection),
program.getIndexedMethod("Iterable.iterator"))));
// i$iterator.hasNext()
JExpression condition = new JMethodCall(info, createVariableRef(info,
iteratorVar), program.getIndexedMethod("Iterator.hasNext"));
// T elementVar = (T) i$iterator.next();
elementDecl.initializer = new JMethodCall(info, createVariableRef(info,
iteratorVar), program.getIndexedMethod("Iterator.next"));
// Perform any implicit reference type casts (due to generics).
// Note this occurs before potential unboxing.
if (elementVar.getType() != program.getTypeJavaLangObject()) {
TypeBinding collectionType;
try {
// TODO: This is slow! Cache lookup.
Field privateField = ForeachStatement.class.getDeclaredField("collectionElementType");
privateField.setAccessible(true);
collectionType = (TypeBinding) privateField.get(x);
} catch (Exception e) {
throw new InternalCompilerException(elementDecl,
"Failed to retreive collectionElementType through reflection",
e);
}
JType toType = (JType) typeMap.get(collectionType);
assert (toType instanceof JReferenceType);
elementDecl.initializer = maybeCast(toType, elementDecl.initializer);
}
body.addStmt(0, elementDecl);
result = new JForStatement(info, initializers, condition,
Collections.<JExpressionStatement> emptyList(), body);
}
// May need to box or unbox the element assignment.
if (x.elementVariableImplicitWidening != -1) {