// 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()); } }