private IEnumerable <Tuple <JsType, TypeOOPEmulationPhase> > Order(IList <Tuple <JsType, TypeOOPEmulationPhase> > source) { var backref = source.ToDictionary(x => x.Item1.CSharpTypeDefinition); var edges = from s in source from t in s.Item2.DependentOnTypes.Intersect(backref.Keys) select Edge.Create(s.Item1.CSharpTypeDefinition, t); var components = TopologicalSorter.FindAndTopologicallySortStronglyConnectedComponents(OrderByNamespace(backref.Keys, x => _metadataImporter.GetTypeSemantics(x).Name), edges); foreach (var error in components.Where(c => c.Count > 1)) { _errorReporter.Region = DomRegion.Empty; _errorReporter.Message(Messages._7802, string.Join(", ", error.Select(t => t.FullName))); } return(components.SelectMany(c => c).Select(t => backref[t])); }
private IEnumerable <JsClass> GetStaticInitializationOrder(IEnumerable <JsClass> types, int pass) { if (pass > 3) { return(types); // If we can't find a non-circular order after 3 passes, just use some random order. } // We run the algorithm in 3 passes, each considering less types of references than the previous one. var dict = types.ToDictionary(t => t.CSharpTypeDefinition, t => new { deps = GetStaticInitializationDependencies(t, pass), backref = t }); var edges = from s in dict from t in s.Value.deps where dict.ContainsKey(t) select Edge.Create(s.Key, t); var result = new List <JsClass>(); foreach (var group in TopologicalSorter.FindAndTopologicallySortStronglyConnectedComponents(dict.Keys.ToList(), edges)) { var backrefed = group.Select(t => dict[t].backref); result.AddRange(group.Count > 1 ? GetStaticInitializationOrder(backrefed.ToList(), pass + 1) : backrefed); } return(result); }
private List <string> RunTest(int numNodes, params string[] edges) { var result = TopologicalSorter.FindAndTopologicallySortStronglyConnectedComponents(Enumerable.Range('a', numNodes).Select(c => ((char)c)), edges.Select(e => Tuple.Create(e[0], e[1]))); return(result.Select(x => new string(x.ToArray())).ToList()); }