[new] add AssemblySorter to sort assemblies by reference order
parent
8e571d594d
commit
9e4946aa45
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b9b8eb45398fa344daa8c6e9b9fbf291
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
Loading…
Reference in New Issue