8.2版本上传
This commit is contained in:
105
Assets/01.HybridCLR/Editor/Meta/AssemblySorter.cs
Normal file
105
Assets/01.HybridCLR/Editor/Meta/AssemblySorter.cs
Normal file
@@ -0,0 +1,105 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user