|
1 | 1 | using System; |
| 2 | +using System.Collections; |
2 | 3 | using System.Collections.Generic; |
3 | 4 | using System.Linq; |
4 | 5 | using dnlib.DotNet; |
5 | 6 |
|
6 | 7 | namespace Confuser.Core { |
7 | 8 | internal sealed class ConfuserAssemblyResolver : IAssemblyResolver { |
8 | | - AssemblyResolver InternalResolver { get; } |
| 9 | + internal AssemblyResolver InternalFuzzyResolver { get; } = new AssemblyResolver { FindExactMatch = false }; |
| 10 | + internal AssemblyResolver InternalExactResolver { get; } = new AssemblyResolver { FindExactMatch = true }; |
9 | 11 |
|
10 | 12 | public bool EnableTypeDefCache { |
11 | | - get => InternalResolver.EnableTypeDefCache; |
12 | | - set => InternalResolver.EnableTypeDefCache = value; |
| 13 | + get => InternalFuzzyResolver.EnableTypeDefCache; |
| 14 | + set { |
| 15 | + InternalFuzzyResolver.EnableTypeDefCache = value; |
| 16 | + InternalExactResolver.EnableTypeDefCache = value; |
| 17 | + } |
13 | 18 | } |
14 | 19 |
|
15 | 20 | public ModuleContext DefaultModuleContext { |
16 | | - get => InternalResolver.DefaultModuleContext; |
17 | | - set => InternalResolver.DefaultModuleContext = value; |
| 21 | + get => InternalFuzzyResolver.DefaultModuleContext; |
| 22 | + set { |
| 23 | + InternalFuzzyResolver.DefaultModuleContext = value; |
| 24 | + InternalExactResolver.DefaultModuleContext = value; |
| 25 | + } |
18 | 26 | } |
19 | 27 |
|
20 | | - public IList<string> PostSearchPaths => InternalResolver.PostSearchPaths; |
21 | | - |
22 | | - internal ConfuserAssemblyResolver() => |
23 | | - InternalResolver = new AssemblyResolver(); |
| 28 | + public IList<string> PostSearchPaths => new TeeList(InternalFuzzyResolver.PostSearchPaths, InternalExactResolver.PostSearchPaths); |
| 29 | + public IList<string> PreSearchPaths => new TeeList(InternalFuzzyResolver.PreSearchPaths, InternalExactResolver.PreSearchPaths); |
24 | 30 |
|
25 | 31 | /// <inheritdoc /> |
26 | 32 | public AssemblyDef Resolve(IAssembly assembly, ModuleDef sourceModule) { |
27 | 33 | if (assembly is AssemblyDef assemblyDef) |
28 | 34 | return assemblyDef; |
29 | 35 |
|
30 | | - var cachedAssemblyDef = InternalResolver |
31 | | - .GetCachedAssemblies() |
32 | | - .FirstOrDefault(a => AssemblyNameComparer.NameAndPublicKeyTokenOnly.Equals(a, assembly)); |
33 | | - if (!(cachedAssemblyDef is null)) |
34 | | - return cachedAssemblyDef; |
| 36 | + var resolvedAssemblyDef = InternalExactResolver.Resolve(assembly, sourceModule); |
| 37 | + return resolvedAssemblyDef ?? InternalFuzzyResolver.Resolve(assembly, sourceModule); |
| 38 | + } |
| 39 | + |
| 40 | + public void Clear() { |
| 41 | + InternalExactResolver.Clear(); |
| 42 | + InternalFuzzyResolver.Clear(); |
| 43 | + } |
| 44 | + |
| 45 | + public IEnumerable<AssemblyDef> GetCachedAssemblies() => |
| 46 | + InternalExactResolver.GetCachedAssemblies().Concat(InternalFuzzyResolver.GetCachedAssemblies()); |
| 47 | + |
| 48 | + public void AddToCache(ModuleDefMD modDef) { |
| 49 | + InternalExactResolver.AddToCache(modDef); |
| 50 | + InternalFuzzyResolver.AddToCache(modDef); |
| 51 | + } |
| 52 | + |
| 53 | + private sealed class TeeList : IList<string> { |
| 54 | + private readonly IList<IList<string>> _lists; |
| 55 | + |
| 56 | + internal TeeList(params IList<string>[] lists) => _lists = lists; |
| 57 | + |
| 58 | + /// <inheritdoc /> |
| 59 | + public IEnumerator<string> GetEnumerator() => _lists[0].GetEnumerator(); |
35 | 60 |
|
36 | | - AssemblyDef resolvedAssemblyDef = null; |
37 | | - try { |
38 | | - InternalResolver.FindExactMatch = true; |
39 | | - resolvedAssemblyDef = InternalResolver.Resolve(assembly, sourceModule); |
| 61 | + /// <inheritdoc /> |
| 62 | + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); |
| 63 | + |
| 64 | + /// <inheritdoc /> |
| 65 | + public void Add(string item) { |
| 66 | + foreach (var list in _lists) |
| 67 | + list.Add(item); |
40 | 68 | } |
41 | | - finally { |
42 | | - InternalResolver.FindExactMatch = false; |
| 69 | + |
| 70 | + /// <inheritdoc /> |
| 71 | + public void Clear() { |
| 72 | + foreach (var list in _lists) |
| 73 | + list.Clear(); |
43 | 74 | } |
44 | 75 |
|
45 | | - return resolvedAssemblyDef ?? InternalResolver.Resolve(assembly, sourceModule); |
46 | | - } |
| 76 | + /// <inheritdoc /> |
| 77 | + public bool Contains(string item) => _lists[0].Contains(item); |
| 78 | + |
| 79 | + /// <inheritdoc /> |
| 80 | + public void CopyTo(string[] array, int arrayIndex) => _lists[0].CopyTo(array, arrayIndex); |
| 81 | + |
| 82 | + /// <inheritdoc /> |
| 83 | + public bool Remove(string item) => |
| 84 | + _lists.Aggregate(true, (current, list) => current | list.Remove(item)); |
| 85 | + |
| 86 | + /// <inheritdoc /> |
| 87 | + public int Count => _lists[0].Count; |
47 | 88 |
|
48 | | - public void Clear() => InternalResolver.Clear(); |
| 89 | + /// <inheritdoc /> |
| 90 | + public bool IsReadOnly => _lists[0].IsReadOnly; |
49 | 91 |
|
50 | | - public IEnumerable<AssemblyDef> GetCachedAssemblies() => InternalResolver.GetCachedAssemblies(); |
| 92 | + /// <inheritdoc /> |
| 93 | + public int IndexOf(string item) => _lists[0].IndexOf(item); |
51 | 94 |
|
52 | | - public void AddToCache(ModuleDefMD modDef) => InternalResolver.AddToCache(modDef); |
| 95 | + /// <inheritdoc /> |
| 96 | + public void Insert(int index, string item) { |
| 97 | + foreach (var list in _lists) |
| 98 | + list.Insert(index, item); |
| 99 | + } |
| 100 | + |
| 101 | + /// <inheritdoc /> |
| 102 | + public void RemoveAt(int index) { |
| 103 | + foreach (var list in _lists) |
| 104 | + list.RemoveAt(index); |
| 105 | + } |
| 106 | + |
| 107 | + /// <inheritdoc /> |
| 108 | + public string this[int index] { |
| 109 | + get => _lists[0][index]; |
| 110 | + set => _lists[0][index] = value; |
| 111 | + } |
| 112 | + } |
53 | 113 | } |
54 | 114 | } |
0 commit comments