Example usage for com.google.common.collect FluentIterable toString

List of usage examples for com.google.common.collect FluentIterable toString

Introduction

In this page you can find the example usage for com.google.common.collect FluentIterable toString.

Prototype

@Override
@CheckReturnValue
public String toString() 

Source Link

Document

Returns a string representation of this fluent iterable, with the format [e1, e2, ..., en] .

Usage

From source file:org.sosy_lab.cpachecker.util.cwriter.PathToCWithLoopsTranslator.java

/**
 * Recreates the code of one (or more nested) loops with gotos.
 * @param pCFAEdge the edge into the loop
 * @param currentBlock the current block
 * @param loopsAfter the loops which we are in after the edge
 * @return the complete c-code for the recreated loop
 *///ww w .j a va 2 s . c  o m
private Pair<String, CFAEdge> recreateLoop(CFAEdge pCFAEdge, BasicBlock currentBlock, List<Loop> loopsAfter) {
    // clear all necessary things
    resetLoopAndIfMaps();

    CFAEdge lastEdge = null;

    // start actual loop recreation
    StringBuilder wholeLoopString = new StringBuilder();

    // we go into a loop thus we have to uproll it right now, and add all
    // handled edges to the handledEdges list, so they wont occur twice in the
    // generated c code

    // this should be already handled by the handledEdges check at the beginning
    // of the processEdge method
    assert loopsAfter.get(loopsAfter.size() - 1).getIncomingEdges().contains(pCFAEdge);

    Loop loop = loopsAfter.get(loopsAfter.size() - 1);

    // create necessary mappings
    String labelStayInLoop = createFreshLabelForLoop(pCFAEdge, loop);

    // uproll loop and write code
    wholeLoopString.append(labelStayInLoop).append(": ;\n");
    Deque<CFAEdge> edgesToHandle = new ArrayDeque<>();
    edgesToHandle.offer(pCFAEdge);

    Deque<Loop> loopStack = new ArrayDeque<>();
    loopStack.push(loop);
    Deque<CFAEdge> ifStack = new ArrayDeque<>();
    Deque<CFAEdge> outOfLoopEdgesStack = new ArrayDeque<>();

    while ((!edgesToHandle.isEmpty() || !outOfLoopEdgesStack.isEmpty() || !ifStack.isEmpty())) {

        // all nodes from the current loop handled, so we can go on to the
        // next one
        if (edgesToHandle.isEmpty()) {
            // at first we need to handle ifs
            if (!ifStack.isEmpty()) {
                edgesToHandle.offer(ifStack.pop());
                wholeLoopString.append("goto ").append(ifOutLabels.get(edgesToHandle.peek())).append(";\n")
                        .append(ifElseLabels.get(edgesToHandle.peek())).append(": ;\n");
            } else {
                edgesToHandle.offer(outOfLoopEdgesStack.pop());
                Loop oldLoop = loopStack.pop();
                wholeLoopString.append("goto ").append(loopInLabels.get(oldLoop)).append(";\n")
                        .append(loopOutLabels.get(oldLoop)).append(": ;\n");
            }
        }

        CFANode currentEdgePredecessor = edgesToHandle.peek().getPredecessor();
        handleIfOutLabels(wholeLoopString, currentEdgePredecessor);

        // only continue if we didn't already visit this edge
        if (handledEdges.contains(edgesToHandle.peek())) {
            edgesToHandle.pop();
            continue;
        }

        CFAEdge currentEdge = edgesToHandle.pop();
        handledEdges.add(currentEdge);
        FluentIterable<CFAEdge> leaving = CFAUtils.leavingEdges(currentEdge.getSuccessor())
                .filter(not(instanceOf(FunctionCallEdge.class)));

        // there was a function call, we need to replace it with the correct successor
        // as we are sure that there is only one, this is safe, we also don't
        // need to update loops here
        if (leaving.isEmpty()) {
            CFAEdge realLeavingEdge = currentEdge.getSuccessor().getLeavingEdge(0);
            CFAEdge leavingSummaryEdge = currentEdge.getSuccessor().getLeavingSummaryEdge();

            wholeLoopString.append(processSimpleWithLoop(realLeavingEdge, currentBlock, ""));
            handledFunctions.add(((CFunctionEntryNode) realLeavingEdge.getSuccessor()).getFunctionName());
            leaving = leaving.append(leavingSummaryEdge);

            // no function call just and ordinary statement, add it as it is
            // to the loopString
        } else if (leaving.size() == 1) {
            wholeLoopString.append(processSimpleWithLoop(leaving.get(0), currentBlock, ""));
        }

        // only one successor, to handle
        // we need to check the loops so that we know if we need
        // to update the loopStack, or only the handledEdges
        if (leaving.size() == 1) {
            CFAEdge onlyEdge = leaving.get(0);

            // this is an edge from inside the loop back to the loop
            if (loopToHead.get(loopStack.peek()) == onlyEdge.getSuccessor()
                    && !loopStack.peek().getIncomingEdges().contains(onlyEdge)) {
                handledEdges.add(onlyEdge);

                handleIfOutLabels(wholeLoopString, onlyEdge.getPredecessor());
            } else {
                edgesToHandle.offer(onlyEdge);
                updateLoopStack(wholeLoopString, loopStack, onlyEdge);
            }

            // more sucessors, we have to add some gotos
        } else {
            // there can be at most two leaving edges
            assert leaving.size() == 2 : leaving.toString();

            CFAEdge leaving1 = leaving.get(0);
            CFAEdge leaving2 = leaving.get(1);

            // outgoing edges have to be handled first, this way
            // we can create the goto easier
            ImmutableSet<CFAEdge> outOfCurrentLoop = loopStack.peek().getOutgoingEdges();

            boolean isOutOfLoopContained = false;
            CFAEdge leavingLoopEdge = null;

            if (outOfCurrentLoop.contains(leaving1)) {
                handleOutOfLoopEdge(currentBlock, wholeLoopString, edgesToHandle, loopStack, leaving1,
                        leaving2);
                leavingLoopEdge = leaving1;
                isOutOfLoopContained = true;

            } else if (outOfCurrentLoop.contains(leaving2)) {
                handleOutOfLoopEdge(currentBlock, wholeLoopString, edgesToHandle, loopStack, leaving2,
                        leaving1);
                leavingLoopEdge = leaving2;
                isOutOfLoopContained = true;
            }

            if (isOutOfLoopContained) {
                // we are alredy in the outermost loop that should be handled
                // if we have an edge which is leaving this loop we just need
                // to create a goto
                if (loopStack.size() == 1) {
                    lastEdge = leavingLoopEdge;
                    handledEdges.add(leavingLoopEdge);

                    // deeper loopstack, potentially the same code as above
                    // we do only need to handle the successor of the outOfLoopEdge, too
                } else {
                    outOfLoopEdgesStack.push(leavingLoopEdge);
                }

                // end this loop iteration here
                continue;
            }

            // now comes the case where both edges stay in the loop, this means
            // this is a "simple" if statement
            // we need to find the merging point of both branches, such that we
            // know where the gotos and labels have to go
            if (!handledEdges.contains(leaving1)) {
                wholeLoopString.append(processSimpleWithLoop(leaving1, currentBlock,
                        createFreshLabelForIf(leaving2,
                                findEndOfBranches(singletonList(loopToHead.get(loopStack.peek())),
                                        currentEdgePredecessor, leaving1.getSuccessor(),
                                        leaving2.getSuccessor()))));
                edgesToHandle.push(leaving1);
                ifStack.push(leaving2);
            }
        }
    }

    wholeLoopString.append("goto ").append(loopInLabels.get(loop)).append(";\n").append(loopOutLabels.get(loop))
            .append(": ;\n");

    //    assert ifOutLabelEnd.isEmpty() && loopStack.isEmpty();
    return Pair.of(wholeLoopString.toString(), lastEdge);
}