}
@Override
public void visitForIntermediate(ForIntermediate line) {
//we need to look at the previous 2 statements and the first statement child.
AbstractIntermediate arrayLenthCandidate = getForExteriorPredecessor(line);
//check that the array length candidate's declared length variable is used in the for's condition.
AbstractIntermediate tempArrayCandidate = null;
AbstractIntermediate firstChild = igc.getTrueTarget(line);
if(arrayLenthCandidate != null) {
tempArrayCandidate = getSinglePredecessor(arrayLenthCandidate);
}
//if either of these are null, then this doesn't match.
if(arrayLenthCandidate == null || tempArrayCandidate == null) {
return;
}
GeneratedVariable generatedArrayLength = extractGeneratedVariableDeclaration(arrayLenthCandidate);
GeneratedVariable generatedArrayReference = extractGeneratedVariableDeclaration(tempArrayCandidate);
GeneratedVariable arrayIteratorValue = extractGeneratedVariableDeclaration(line.getInit());
if(generatedArrayLength == null || generatedArrayReference == null || arrayIteratorValue == null) {
return;
}
//now validate the types. array length should be an integer. the array reference, well, should be an array ;)
//the iterator should be an integer.
if(generatedArrayLength.getType() != Type.INT) {
if(!(generatedArrayReference.getType() instanceof ArrayType)) {
return;
}
if(arrayIteratorValue.getType() != Type.INT) {
return;
}
}
//great; at this point we know the pattern matches. check the next statement to see if the transformation is possible.
//format should be: 40 : GENERATED_ARRAY_REFERENCE_TYPE i = GENERATED_ARRAY_REFERENCE[ARRAY_ITERATOR_VALUE] |
StatementIntermediate childDeclarationStatement = ((StatementIntermediate)firstChild);
Declaration childDeclaration = (Declaration)childDeclarationStatement.getExpression();
if(firstMatchesGeneratedVariables(childDeclarationStatement, generatedArrayReference, arrayIteratorValue)) {
LOG.debug("Likely a enhanced for loop for array: "+generatedArrayLength + " , "+ generatedArrayReference);
//we are good to go here. Now we just need to reorganize the graph. Start by creating the new enhanced for loop.
EnhancedForIntermediate efl = new EnhancedForIntermediate(line.getInstruction(), line.getConditionalIntermediate(), childDeclaration.getVariable(), extractExpressionFromGeneratedArrayAssignment(tempArrayCandidate));
//efl.setTrueBranch(line.getTrueBranch());
//efl.setFalseBranch(line.getFalseBranch());
//add the new node...
this.igc.getGraph().addVertex(efl);
//now, we just need to redirect.
igc.redirectPredecessors(tempArrayCandidate, efl);
igc.redirectPredecessors(line, efl);
igc.redirectSuccessors(line, efl);
AbstractIntermediate nextChild = getSingleSuccessor(firstChild);
igc.redirectPredecessors(firstChild, nextChild);
//remove line.
igc.getGraph().removeVertex(line);
igc.getGraph().removeVertex(tempArrayCandidate);