예제 #1
0
        /// <summary>
        /// Recursive method used for generating the body of text representation of controlflow graph.
        /// It generates the result for globalcode and dureing the generation it calls
        /// itself resursivly on controlflow graphs of declared functions and methods.
        /// </summary>
        /// <param name="counter">Body of string representation in dot language of current conftrolflow graph.</param>
        /// <returns></returns>
        private string generateText(int counter)
        {
            string            result = "";
            List <BasicBlock> nodes  = CollectAllBasicBlocks();

            /*
             * generating text for all nodes
             */
            string functionsResult = "";
            int    i          = counter;
            int    oldCounter = counter;

            foreach (var node in nodes)
            {
                string label = "";
                foreach (var statement in node.Statements)
                {
                    /*
                     * recursive generating cfg and text representation for function
                     */
                    if (statement.GetType() == typeof(FunctionDecl))
                    {
                        FunctionDecl function = (FunctionDecl)statement;
                        label += "function " + function.Function.Name + Environment.NewLine;

                        try
                        {
                            ControlFlowGraph cfg = new ControlFlowGraph(globalCode, function, File);
                            functionsResult += cfg.generateText((counter / 10000 + 1) * 10000);
                            counter         += 10000;
                        }
                        catch (Weverca.ControlFlowGraph.ControlFlowException e)
                        {
                            Console.WriteLine(e.Message);
                            return("");
                        }
                    }

                    /*
                     * recursive generating cfg and text representation for objects
                     */
                    else if (statement.GetType() == typeof(TypeDecl))
                    {
                        TypeDecl clas = (TypeDecl)statement;
                        label += "class " + clas.Name.ToString() + Environment.NewLine;
                        foreach (var method in clas.Members)
                        {
                            if (method.GetType() == typeof(MethodDecl))
                            {
                                try
                                {
                                    ControlFlowGraph cfg = new ControlFlowGraph(globalCode, method as MethodDecl, File);
                                    functionsResult += cfg.generateText((counter / 10000 + 1) * 10000);
                                    counter         += 10000;
                                }
                                catch (Weverca.ControlFlowGraph.ControlFlowException e)
                                {
                                    Console.WriteLine(e.Message);
                                    return("");
                                }
                            }
                        }
                    }
                    else if (statement is ForeachStmt)
                    {
                        var      forEach             = statement as ForeachStmt;
                        Position foreachHeadPosition = new Position(forEach.Position.FirstLine, forEach.Position.FirstColumn, forEach.Position.FirstOffset,
                                                                    forEach.Body.Position.FirstLine, forEach.Body.Position.FirstColumn, forEach.Body.Position.FirstOffset - 1);
                        label += globalCode.SourceUnit.GetSourceCode(foreachHeadPosition) + Environment.NewLine;
                    }
                    else
                    {
                        label += globalCode.SourceUnit.GetSourceCode(statement.Position) + Environment.NewLine;
                    }
                }
                if (node.EndIngTryBlocks.Count > 0)
                {
                    label += "//ending Try block";
                }
                label   = label.Replace("\"", "\\\"");
                result += "node" + i + "[label=\"" + label + "\"]" + Environment.NewLine;
                i++;
            }

            /*
             * drawing edges
             */
            i = oldCounter;
            foreach (var node in nodes)
            {
                foreach (var e in node.OutgoingEdges)
                {
                    int index = oldCounter + nodes.IndexOf(e.To);
                    if (e.EdgeType == BasicBlockEdgeTypes.CONDITIONAL)
                    {
                        string label = "";
                        //in case a condition is not from original ast and hes been aded in constructiion of cfg, we need to write it in different way
                        if (!e.Condition.Position.IsValid || this.cfgAddedElements.Contains(e.Condition))
                        {
                            if (e.Condition.GetType() == typeof(BoolLiteral))
                            {
                                label = e.Condition.Value.ToString();
                            }
                            if (e.Condition.GetType() == typeof(BinaryEx))
                            {
                                BinaryEx bin = (BinaryEx)e.Condition;
                                //dirty trick how to acces internal field
                                var a = bin.GetType().GetField("operation", BindingFlags.NonPublic | BindingFlags.Instance);
                                if ((Operations)a.GetValue(bin) == Operations.Equal)
                                {
                                    Expression l = (Expression)bin.GetType().GetField("leftExpr", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(bin);
                                    Expression r = (Expression)bin.GetType().GetField("rightExpr", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(bin);
                                    if (l.Position.IsValid == false)
                                    {
                                        if (l.GetType() == typeof(IntLiteral))
                                        {
                                            label += "" + ((IntLiteral)l).Value;
                                            label += "=";
                                            label += globalCode.SourceUnit.GetSourceCode(r.Position);
                                        }
                                        else
                                        {
                                            label += "else";
                                        }
                                    }
                                    else
                                    {
                                        label += globalCode.SourceUnit.GetSourceCode(l.Position);
                                        label += "=";
                                        label += globalCode.SourceUnit.GetSourceCode(r.Position);
                                    }
                                }
                                else
                                {
                                    label += "else";
                                    //label = globalCode.SourceUnit.GetSourceCode(edge.Condition.Position);
                                }
                            }
                            if (e.Condition.GetType() == typeof(DirectFcnCall))
                            {
                                DirectFcnCall functionCall = (DirectFcnCall)e.Condition;

                                label += functionCall.QualifiedName + "(";
                                foreach (var parameter in functionCall.CallSignature.Parameters)
                                {
                                    if (parameter.Expression.GetType() == typeof(StringLiteral))
                                    {
                                        StringLiteral literal = (StringLiteral)parameter.Expression;
                                        label += "\"" + literal.Value + "\"" + ",";
                                    }
                                    else
                                    {
                                        label += globalCode.SourceUnit.GetSourceCode(parameter.Expression.Position) + ",";
                                    }
                                }
                                label += ")";
                            }
                        }
                        else
                        {
                            label = globalCode.SourceUnit.GetSourceCode(e.Condition.Position);
                        }
                        label   = label.Replace("\"", "\\\"");
                        result += "node" + i + " -> node" + index + "[headport=n, tailport=s,label=\"" + label + "\"]" + Environment.NewLine;
                    }
                    else if (e.EdgeType == BasicBlockEdgeTypes.FOREACH)
                    {
                        result += "node" + i + " -> node" + index + "[headport=n, tailport=s,label=\"foreach special edge\"]" + Environment.NewLine;
                    }
                    else
                    {
                        result += "node" + i + " -> node" + index + "[headport=n, tailport=s,label=\"direct edge\"]" + Environment.NewLine;
                    }
                }
                if (node.DefaultBranch != null)
                {
                    string elseString = string.Empty;
                    if (node.OutgoingEdges.Count > 0)
                    {
                        elseString = "else";
                    }

                    int index = oldCounter + nodes.IndexOf(node.DefaultBranch.To);
                    result += "node" + i + " -> node" + index + "[headport=n, tailport=s,label=\" " + elseString + "  \"]" + Environment.NewLine;
                }
                if (node.EndIngTryBlocks.Count > 0)
                {
                    foreach (var tryblock in node.EndIngTryBlocks)
                    {
                        foreach (var catchblock in tryblock.catchBlocks)
                        {
                            int index = oldCounter + nodes.IndexOf(catchblock);
                            result += "node" + i + " -> node" + index + "[headport=n, tailport=s,label=\" catched " + catchblock.ClassName.QualifiedName.Name.Value + "  \"]" + Environment.NewLine;
                        }
                    }
                }
                i++;
            }
            result += functionsResult;
            result += Environment.NewLine;
            return(result);
        }