Ejemplo n.º 1
0
 public CallGraphOrder(
     bool constructorsFirst,
     IDecodeMetaData <Local, Parameter, Method, Field, Property, Event, Type, Attribute, Assembly> md,
     IDecodeContracts <Local, Parameter, Method, Field, Type> cd,
     Set <string> underAnalysis,
     FieldsDB <Local, Parameter, Method, Field, Property, Event, Type, Attribute, Assembly> fieldsDB,
     CancellationToken cancellationToken)
     : base(md, cd, fieldsDB)
 {
     this.constructorsFirst       = constructorsFirst;
     this.callGraph               = new SingleEdgeGraph <Node, Unit>(null, new Node.EqualityComparer(md));
     this.assembliesUnderAnalysis = underAnalysis;
     this.contractConsumer        = new ContractConsumer(this);
     this.cancellationToken       = cancellationToken;
 }
Ejemplo n.º 2
0
        // Callgraph-ordered
        public override IEnumerable <Method> OrderedMethods()
        {
            var components = StronglyConnectedComponents.Compute(this.callGraph);

            // components are in caller to callee order, so reverse it
            components.Reverse();

            var classGraph    = new SingleEdgeGraph <Type, Unit>(null);
            var mAlreadyThere = new Set <Type>();
            Predicate <Node> nodeStartVisitor = n =>
            {
                if (n.Kind != Node.Tag.method)
                {
                    return(true);
                }
                var m  = n.Method;
                var dt = this.md.DeclaringType(m);
                if (mAlreadyThere.Add(dt))
                {
                    classGraph.AddNode(dt);
                }
                // add edge dt -> type(each successor)
                foreach (var suc in this.callGraph.Successors(n))
                {
                    if (suc.Two.Kind != Node.Tag.method)
                    {
                        continue;
                    }
                    var succmethod = suc.Two.Method;
                    var tsuc       = this.md.DeclaringType(succmethod);
                    if (mAlreadyThere.Add(tsuc))
                    {
                        classGraph.AddNode(tsuc);
                    }
                    classGraph.AddEdge(dt, Unit.Value, tsuc);
                }
                return(true);
            };
            var dfs_construct_class_graph = new DepthFirst.Visitor <Node, Unit>(this.callGraph, nodeStartVisitor);

            dfs_construct_class_graph.VisitAll();

            // Now get the ordering of the class graph
            var class_components = StronglyConnectedComponents.Compute(classGraph);

            class_components.Reverse();

            // Stores the class order
            var class_order = new Dictionary <Type, int>();
            int index       = 0;

            foreach (var compo in class_components)
            {
                foreach (var cl in compo)
                {
                    class_order.Add(cl, index++);
                }
            }

            var indexes = new Dictionary <Method, int>();

            Comparison <Method> compareMethods = (m1, m2) =>
            {
                var t1 = class_order[this.md.DeclaringType(m1)];
                var t2 = class_order[this.md.DeclaringType(m2)];
                if (t1 != t2)
                {
                    return(t2 - t1);
                }
                // regarding to class order, m1 == m2, i.e. keep global methods order
                return(indexes[m2] - indexes[m1]);
            };

            // Stores the global method order to decide inside class graph strong components
            // And populate the method list
            var ordered_methods = new PriorityQueue <Method>(compareMethods);

            index = 0;
            foreach (var component in components)
            {
                foreach (var node in component)
                {
                    if (node.Kind == Node.Tag.method)
                    {
                        indexes[node.Method] = index++;
                        ordered_methods.Add(node.Method);
                    }
                }
            }

            while (ordered_methods.Count > 0)
            {
                yield return(ordered_methods.Pull());
            }
        }