/// <summary>
 /// Removes the nodes added to the new try construct from the orderedCFGNodes collection.
 /// </summary>
 /// <param name="theNewTryConstruct"></param>
 private void CleanUpOrderedNodes(TryFinallyLogicalConstruct theNewTryConstruct)
 {
     foreach (CFGBlockLogicalConstruct cfgChild in theNewTryConstruct.CFGBlocks)
     {
         orderedCFGNodes.Remove(cfgChild);
     }
 }
 private void GenerateTryFinallyHandler(YieldExceptionHandlerInfo handlerInfo)
 {
     this.finallyBlocks = new HashSet <ILogicalConstruct>();
     this.entryOfTry    = this.GetStateBeginBlockConstruct(handlerInfo.get_TryStates());
     this.BuildTryBody(handlerInfo);
     if (handlerInfo.get_HandlerType() != YieldExceptionHandlerType.Method)
     {
         V_0 = this.GenerateFinallyBlock();
     }
     else
     {
         if (this.newFinallyBody == null)
         {
             throw new Exception("Could not determine the end ot the try block");
         }
         this.RemoveExcessNodesFromTheTryBlock();
         this.ProcessFinallyNodes();
         stackVariable31    = this.newFinallyBody;
         stackVariable33    = new ILogicalConstruct[1];
         stackVariable33[0] = this.newFinallyBody;
         V_0 = new BlockLogicalConstruct(stackVariable31, stackVariable33);
     }
     V_1 = new TryFinallyLogicalConstruct(new BlockLogicalConstruct(this.entryOfTry, this.newTryBody), V_0);
     this.createdConstructsToIntervalMap.set_Item(V_1, handlerInfo);
     this.CleanUpOrderedNodes(V_1);
     return;
 }
        /// <summary>
        /// Generates the try/finally construct that is represented by the specifed exception handler info and attaches it to the logical tree.
        /// </summary>
        /// <param name="handlerInfo"></param>
        private void GenerateTryFinallyHandler(YieldExceptionHandlerInfo handlerInfo)
        {
            finallyBlocks = new HashSet <ILogicalConstruct>();

            entryOfTry = GetStateBeginBlockConstruct(handlerInfo.TryStates);

            BuildTryBody(handlerInfo);

            BlockLogicalConstruct newFinally;

            if (handlerInfo.HandlerType == YieldExceptionHandlerType.Method)
            {
                if (newFinallyBody == null)
                {
                    throw new Exception("Could not determine the end ot the try block");
                }

                RemoveExcessNodesFromTheTryBlock();

                ProcessFinallyNodes();

                newFinally = new BlockLogicalConstruct(newFinallyBody, new ILogicalConstruct[] { newFinallyBody });
            }
            else
            {
                newFinally = GenerateFinallyBlock();
            }

            BlockLogicalConstruct      newTry = new BlockLogicalConstruct(entryOfTry, newTryBody);
            TryFinallyLogicalConstruct newTryFinallyConstruct = new TryFinallyLogicalConstruct(newTry, newFinally);

            createdConstructsToIntervalMap[newTryFinallyConstruct] = handlerInfo;

            CleanUpOrderedNodes(newTryFinallyConstruct);
        }
 private void CleanUpOrderedNodes(TryFinallyLogicalConstruct theNewTryConstruct)
 {
     V_0 = theNewTryConstruct.get_CFGBlocks().GetEnumerator();
     try
     {
         while (V_0.MoveNext())
         {
             V_1       = V_0.get_Current();
             dummyVar0 = this.orderedCFGNodes.Remove(V_1);
         }
     }
     finally
     {
         ((IDisposable)V_0).Dispose();
     }
     return;
 }
        /// <summary>
        /// Checks each a node before adding its successors to the <paramref name="bfsQueue"/>.
        /// </summary>
        /// <remarks>
        /// If the node is a CFGBlockLC and it contains the invocation of the finally method, or the entry of the finally block,
        /// then we should not continue the traversal.
        /// </remarks>
        /// <param name="handlerInfo"></param>
        /// <param name="bfsQueue"></param>
        /// <param name="currentNode"></param>
        private void ProcessCurrentNode(YieldExceptionHandlerInfo handlerInfo, Queue <ILogicalConstruct> bfsQueue, ILogicalConstruct currentNode)
        {
            if (currentNode is CFGBlockLogicalConstruct)
            {
                CFGBlockLogicalConstruct currentCFGNode = currentNode as CFGBlockLogicalConstruct;
                for (int i = 0; i < currentCFGNode.LogicalConstructExpressions.Count; i++)
                {
                    Expression currentExpression = currentCFGNode.LogicalConstructExpressions[i];

                    int value;
                    if (TryGetStateAssignValue(currentExpression, out value))
                    {
                        if (!handlerInfo.TryStates.Contains(value)) //sanity check
                        {
                            if (handlerInfo.HandlerType != YieldExceptionHandlerType.Method &&
                                TryProcessConditionalDisposeHandler(handlerInfo, currentCFGNode))
                            {
                                return;
                            }
                            throw new Exception("Invalid state value");
                        }
                    }
                    else if (handlerInfo.HandlerType == YieldExceptionHandlerType.Method &&
                             currentExpression.CodeNodeType == CodeNodeType.MethodInvocationExpression &&
                             (currentExpression as MethodInvocationExpression).MethodExpression.MethodDefinition == handlerInfo.FinallyMethodDefinition)
                    {
                        //For the finally block we need the CFGBlockLC that contains only the invocation of the finally method.
                        //That's why we need to split the CFGBlockLC, if there are other expressions besides the invocation.
                        CFGBlockLogicalConstruct currentFinallyBlock;
                        if (currentCFGNode.LogicalConstructExpressions.Count == 1)
                        {
                            if (newFinallyBody == null)
                            {
                                newFinallyBody = currentCFGNode;
                            }
                            finallyBlocks.Add(newFinallyBody);
                            orderedCFGNodes.Remove(currentCFGNode);
                            return;
                        }

                        if (i == 0)
                        {
                            KeyValuePair <CFGBlockLogicalConstruct, CFGBlockLogicalConstruct> newConstructsPair =
                                LogicalFlowUtilities.SplitCFGBlockAt(logicalContext, currentCFGNode, i + 1);

                            currentFinallyBlock = newConstructsPair.Key;
                            orderedCFGNodes[orderedCFGNodes.IndexOf(currentCFGNode)] = newConstructsPair.Value;
                        }
                        else if (i < currentCFGNode.LogicalConstructExpressions.Count - 1)
                        {
                            KeyValuePair <CFGBlockLogicalConstruct, CFGBlockLogicalConstruct> endOfTryPair =
                                LogicalFlowUtilities.SplitCFGBlockAt(logicalContext, currentCFGNode, i);
                            newTryBody.Add(endOfTryPair.Key);

                            KeyValuePair <CFGBlockLogicalConstruct, CFGBlockLogicalConstruct> finallyRestOfBlockPair =
                                LogicalFlowUtilities.SplitCFGBlockAt(logicalContext, endOfTryPair.Value, 1);

                            currentFinallyBlock = finallyRestOfBlockPair.Key;
                            orderedCFGNodes[orderedCFGNodes.IndexOf(currentCFGNode)] = finallyRestOfBlockPair.Value;
                        }
                        else // i == count - 1
                        {
                            KeyValuePair <CFGBlockLogicalConstruct, CFGBlockLogicalConstruct> tryFinallyPair =
                                LogicalFlowUtilities.SplitCFGBlockAt(logicalContext, currentCFGNode, i);

                            newTryBody.Add(tryFinallyPair.Key);
                            currentFinallyBlock = tryFinallyPair.Value;

                            orderedCFGNodes.Remove(currentCFGNode);
                        }

                        if (newFinallyBody == null)
                        {
                            newFinallyBody = currentFinallyBlock;
                        }
                        finallyBlocks.Add(currentFinallyBlock);

                        return;
                    }
                }
            }
            else if (currentNode is TryFinallyLogicalConstruct)
            {
                TryFinallyLogicalConstruct tryFinallyConstruct = currentNode as TryFinallyLogicalConstruct;
                YieldExceptionHandlerInfo  oldHandlerInfo;
                if (createdConstructsToIntervalMap.TryGetValue(tryFinallyConstruct, out oldHandlerInfo) &&
                    oldHandlerInfo.TryStates.IsProperSupersetOf(handlerInfo.TryStates))
                {
                    throw new Exception("This try/finally construct cannot be nested in the current construct");
                }
            }

            newTryBody.Add(currentNode);
            foreach (ILogicalConstruct successor in currentNode.SameParentSuccessors)
            {
                bfsQueue.Enqueue(successor);
            }
        }