123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace HybridCLR.Editor.Meta
- {
- public class AssemblySorter
- {
- class Node
- {
- public string Name;
- public List<Node> Dependencies = new List<Node>();
- public Node(string name)
- {
- Name = name;
- }
- }
- class TopologicalSorter
- {
- public static List<Node> Sort(List<Node> nodes)
- {
- List<Node> sorted = new List<Node>();
- HashSet<Node> visited = new HashSet<Node>();
- HashSet<Node> tempMarks = new HashSet<Node>();
- foreach (var node in nodes)
- {
- if (!visited.Contains(node))
- {
- Visit(node, visited, tempMarks, sorted);
- }
- }
- return sorted;
- }
- private static void Visit(Node node, HashSet<Node> visited, HashSet<Node> tempMarks, List<Node> sorted)
- {
- if (tempMarks.Contains(node))
- {
- throw new Exception("Detected cyclic dependency!");
- }
- if (!visited.Contains(node))
- {
- tempMarks.Add(node);
- foreach (var dependency in node.Dependencies)
- {
- Visit(dependency, visited, tempMarks, sorted);
- }
- tempMarks.Remove(node);
- visited.Add(node);
- sorted.Add(node);
- }
- }
- }
- private static List<string> SortAssemblyByReferenceOrder(IEnumerable<string> assemblies, Dictionary<string, HashSet<string>> refs)
- {
- var nodes = new List<Node>();
- var nodeMap = new Dictionary<string, Node>();
- foreach (var assembly in assemblies)
- {
- var node = new Node(assembly);
- nodes.Add(node);
- nodeMap.Add(assembly, node);
- }
- foreach (var assembly in assemblies)
- {
- var node = nodeMap[assembly];
- foreach (var refAssembly in refs[assembly])
- {
- node.Dependencies.Add(nodeMap[refAssembly]);
- }
- }
- var sortedNodes = TopologicalSorter.Sort(nodes);
- return sortedNodes.Select(node => node.Name).ToList();
- }
- public static List<string> SortAssemblyByReferenceOrder(IEnumerable<string> assemblies, IAssemblyResolver assemblyResolver)
- {
- var assCache = new AssemblyCache(assemblyResolver);
- var assRefAssemblies = new Dictionary<string, HashSet<string>>();
- foreach (var assName in assemblies)
- {
- var refAssemblies = new HashSet<string>();
- var mod = assCache.LoadModule(assName, false);
- foreach (var refAss in mod.GetAssemblyRefs())
- {
- if (assemblies.Contains(refAss.Name.ToString()))
- {
- refAssemblies.Add(refAss.Name.ToString());
- }
- }
- assRefAssemblies.Add(assName, refAssemblies);
- }
- return SortAssemblyByReferenceOrder(assemblies, assRefAssemblies);
- }
- }
- }
|