private ISet <CFGEdge> IdentifyBackEdges()
        {
            var back_edges = new HashSet <CFGEdge>();

            foreach (var node in cfg.Nodes)
            {
                foreach (var succ in node.Successors)
                {
                    if (node.Dominators.Contains(succ))
                    {
                        var edge = new CFGEdge(node, succ);
                        back_edges.Add(edge);
                    }
                }
            }

            return(back_edges);
        }
        private static CFGLoop IdentifyLoop(CFGEdge back_edge)
        {
            var loop  = new CFGLoop(back_edge.Target);
            var nodes = new Stack <CFGNode>();

            nodes.Push(back_edge.Source);

            do
            {
                var node     = nodes.Pop();
                var new_node = loop.Body.Add(node);

                if (new_node)
                {
                    foreach (var pred in node.Predecessors)
                    {
                        nodes.Push(pred);
                    }
                }
            }while (nodes.Count > 0);

            return(loop);
        }
Beispiel #3
0
        public void AfterRun(IPexPathComponent host, object data)
        {
            MessageBox.Show("AfterRun");

            // Getting the executions nodes in the current path
            var nodesInPath = host.PathServices.CurrentExecutionNodeProvider.ReversedNodes.Reverse().ToArray();

            // Getting the sequence id of the current run
            var runId = host.ExplorationServices.Driver.Runs;

            // Iterating over the nodes in the path
            foreach (var node in nodesInPath)
            {
                var vertex = new CFGNode(node.UniqueIndex, false);

                // Adding the method name this early in order to color edges
                string methodName = null;
                int    offset     = 0;
                if (node.CodeLocation.Method == null)
                {
                    if (node.InCodeBranch.Method != null)
                    {
                        methodName = node.InCodeBranch.Method.FullName;
                    }
                }
                else
                {
                    methodName = node.CodeLocation.Method.FullName;
                    offset     = node.CodeLocation.Offset;
                }
                // Setting the method name
                vertex.MethodName = methodName;

                // Setting the offset
                vertex.ILOffset = (uint)offset;

                var nodeIndex = nodesInPath.ToList().IndexOf(node);
                if (nodeIndex > 0)
                {
                    var prevNode = nodesInPath [nodeIndex - 1];
                    // If there is no edge between the previous and the current node
                    if (!(Edges.ContainsKey(prevNode.UniqueIndex) && Edges [prevNode.UniqueIndex].ContainsKey(node.UniqueIndex)))
                    {
                        var prevVertex = Vertices [prevNode.UniqueIndex];

                        var edge = new CFGEdge(new Random().Next(), prevVertex, vertex);

                        Dictionary <int, CFGEdge> outEdges = null;
                        if (Edges.TryGetValue(prevNode.UniqueIndex, out outEdges))
                        {
                            outEdges.Add(node.UniqueIndex, edge);
                        }
                        else
                        {
                            Edges.Add(prevNode.UniqueIndex, new Dictionary <int, CFGEdge>());
                            Edges [prevNode.UniqueIndex].Add(node.UniqueIndex, edge);
                        }

                        // Edge coloring based on unit border detection
                        if (UnitNamespace != null)
                        {
                            // Checking if pointing into the unit from outside
                            if (!(prevVertex.MethodName.StartsWith(UnitNamespace + ".") || prevVertex.MethodName.Equals(UnitNamespace)) && (vertex.MethodName.StartsWith(UnitNamespace + ".") || vertex.MethodName.Equals(UnitNamespace)))
                            {
                                edge.Color = CFGEdge.EdgeColor.Green;
                            }

                            // Checking if pointing outside the unit from inside
                            if ((prevVertex.MethodName.StartsWith(UnitNamespace + ".") || prevVertex.MethodName.Equals(UnitNamespace)) && !(vertex.MethodName.StartsWith(UnitNamespace + ".") || vertex.MethodName.Equals(UnitNamespace)))
                            {
                                edge.Color = CFGEdge.EdgeColor.Red;
                            }
                        }
                    }
                }

                // If the node is new then it is added to the list and the metadata is filled
                if (!Vertices.ContainsKey(node.UniqueIndex))
                {
                    Vertices.Add(node.UniqueIndex, vertex);

                    // Adding source code mapping
                    vertex.SourceCodeMappingString = MapToSourceCodeLocationString(host, node);

                    // Setting the border based on mapping existence
                    vertex.Border = vertex.SourceCodeMappingString == null ? CFGNode.NodeBorder.Single : CFGNode.NodeBorder.Double;

                    // Setting the color
                    if (nodesInPath.LastOrDefault() == node)
                    {
                        if (!EmittedTestResult.ContainsKey(runId))
                        {
                            vertex.Color = CFGNode.NodeColor.Orange;
                        }
                        else
                        {
                            if (EmittedTestResult [runId].Item1)
                            {
                                vertex.Color = CFGNode.NodeColor.Red;
                            }
                            else
                            {
                                vertex.Color = CFGNode.NodeColor.Green;
                            }
                            vertex.GenerateTestCode = EmittedTestResult [runId].Item2;
                        }
                    }
                    else
                    {
                        vertex.Color = CFGNode.NodeColor.White;
                    }

                    // Setting the default shape
                    vertex.Shape = CFGNode.NodeShape.Rectangle;

                    // Adding path condition tasks and getting the required services
                    TermEmitter       termEmitter      = new TermEmitter(host.GetService <TermManager>());
                    SafeStringWriter  safeStringWriter = new SafeStringWriter();
                    IMethodBodyWriter methodBodyWriter = host.GetService <IPexTestManager>().Language.CreateBodyWriter(safeStringWriter, VisibilityContext.Private, 2000);
                    PrettyPathConditionTasks.Add(vertex.Id, PrettyPrintPathCondition(termEmitter, methodBodyWriter, safeStringWriter, node));

                    // Setting the status
                    vertex.Status = node.ExhaustedReason.ToString();

                    // Collecting the parent nodes for the later incremental path condition calculation
                    if (nodeIndex > 0)
                    {
                        ParentNodes.Add(vertex.Id, nodesInPath [nodeIndex - 1].UniqueIndex);
                    }
                }

                // Adding the Id of the run
                Vertices [node.UniqueIndex].Runs += (runId + ";");
            }
        }