Skip to content

Commit 9e4946a

Browse files
committed
[new] add AssemblySorter to sort assemblies by reference order
1 parent 8e571d5 commit 9e4946a

2 files changed

Lines changed: 116 additions & 0 deletions

File tree

Editor/Meta/AssemblySorter.cs

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace HybridCLR.Editor.Meta
8+
{
9+
10+
public class AssemblySorter
11+
{
12+
class Node
13+
{
14+
public string Name;
15+
public List<Node> Dependencies = new List<Node>();
16+
17+
public Node(string name)
18+
{
19+
Name = name;
20+
}
21+
}
22+
23+
class TopologicalSorter
24+
{
25+
26+
public static List<Node> Sort(List<Node> nodes)
27+
{
28+
List<Node> sorted = new List<Node>();
29+
HashSet<Node> visited = new HashSet<Node>();
30+
HashSet<Node> tempMarks = new HashSet<Node>();
31+
32+
foreach (var node in nodes)
33+
{
34+
if (!visited.Contains(node))
35+
{
36+
Visit(node, visited, tempMarks, sorted);
37+
}
38+
}
39+
return sorted;
40+
}
41+
42+
private static void Visit(Node node, HashSet<Node> visited, HashSet<Node> tempMarks, List<Node> sorted)
43+
{
44+
if (tempMarks.Contains(node))
45+
{
46+
throw new Exception("Detected cyclic dependency!");
47+
}
48+
49+
if (!visited.Contains(node))
50+
{
51+
tempMarks.Add(node);
52+
foreach (var dependency in node.Dependencies)
53+
{
54+
Visit(dependency, visited, tempMarks, sorted);
55+
}
56+
tempMarks.Remove(node);
57+
visited.Add(node);
58+
sorted.Add(node);
59+
}
60+
}
61+
}
62+
63+
private static List<string> SortAssemblyByReferenceOrder(IEnumerable<string> assemblies, Dictionary<string, HashSet<string>> refs)
64+
{
65+
var nodes = new List<Node>();
66+
var nodeMap = new Dictionary<string, Node>();
67+
foreach (var assembly in assemblies)
68+
{
69+
var node = new Node(assembly);
70+
nodes.Add(node);
71+
nodeMap.Add(assembly, node);
72+
}
73+
foreach (var assembly in assemblies)
74+
{
75+
var node = nodeMap[assembly];
76+
foreach (var refAssembly in refs[assembly])
77+
{
78+
node.Dependencies.Add(nodeMap[refAssembly]);
79+
}
80+
}
81+
var sortedNodes = TopologicalSorter.Sort(nodes);
82+
return sortedNodes.Select(node => node.Name).ToList();
83+
}
84+
85+
public static List<string> SortAssemblyByReferenceOrder(IEnumerable<string> assemblies, IAssemblyResolver assemblyResolver)
86+
{
87+
var assCache = new AssemblyCache(assemblyResolver);
88+
var assRefAssemblies = new Dictionary<string, HashSet<string>>();
89+
foreach (var assName in assemblies)
90+
{
91+
var refAssemblies = new HashSet<string>();
92+
var mod = assCache.LoadModule(assName, false);
93+
foreach (var refAss in mod.GetAssemblyRefs())
94+
{
95+
if (assemblies.Contains(refAss.Name.ToString()))
96+
{
97+
refAssemblies.Add(refAss.Name.ToString());
98+
}
99+
}
100+
assRefAssemblies.Add(assName, refAssemblies);
101+
}
102+
return SortAssemblyByReferenceOrder(assemblies, assRefAssemblies);
103+
}
104+
}
105+
}

Editor/Meta/AssemblySorter.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)