-
Notifications
You must be signed in to change notification settings - Fork 396
Expand file tree
/
Copy pathClassUtil.cs
More file actions
75 lines (64 loc) · 1.8 KB
/
ClassUtil.cs
File metadata and controls
75 lines (64 loc) · 1.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using ReClassNET.Extensions;
using ReClassNET.Util;
namespace ReClassNET.Nodes
{
public class ClassUtil
{
internal static IEnumerable<ClassNode> Classes;
public static bool IsCycleFree(ClassNode parent, ClassNode check)
{
Contract.Requires(parent != null);
Contract.Requires(check != null);
if (Classes == null)
{
return true;
}
return IsCycleFree(parent, check, Classes);
}
public static bool IsCycleFree(ClassNode parent, ClassNode check, IEnumerable<ClassNode> classes)
{
Contract.Requires(parent != null);
Contract.Requires(check != null);
Contract.Requires(classes != null);
Contract.Requires(Contract.ForAll(classes, c => c != null));
var toCheck = new HashSet<ClassNode>(
check.Yield()
.Traverse(
c => c.Nodes
.Where(n => n is ClassInstanceNode || n is ClassInstanceArrayNode)
.Select(n => ((BaseReferenceNode)n).InnerNode)
)
);
return IsCycleFree(parent, toCheck, classes);
}
private static bool IsCycleFree(ClassNode root, HashSet<ClassNode> seen, IEnumerable<ClassNode> classes)
{
Contract.Requires(root != null);
Contract.Requires(seen != null);
Contract.Requires(Contract.ForAll(seen, c => c != null));
Contract.Requires(Contract.ForAll(classes, c => c != null));
if (!seen.Add(root))
{
return false;
}
var classNodes = classes as IList<ClassNode> ?? classes.ToList();
foreach (var cls in classNodes/*.Except(seen)*/)
{
if (cls.Nodes
.OfType<BaseReferenceNode>()
.Where(n => n is ClassInstanceNode || n is ClassInstanceArrayNode)
.Any(n => n.InnerNode == root))
{
if (!IsCycleFree(cls, seen, classNodes))
{
return false;
}
}
}
return true;
}
}
}