SymbolResolver.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. #if ENABLE_MONO && (DEVELOPMENT_BUILD || UNITY_EDITOR)
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Reflection;
  5. using SingularityGroup.HotReload.DTO;
  6. using SingularityGroup.HotReload.RuntimeDependencies;
  7. namespace SingularityGroup.HotReload {
  8. internal class SymbolResolver {
  9. readonly Dictionary<string, List<Assembly>> assembliesByName;
  10. public SymbolResolver(Dictionary<string, List<Assembly>> assembliesByName) {
  11. this.assembliesByName = assembliesByName;
  12. }
  13. public void AddAssembly(Assembly asm) {
  14. var asmName = asm.GetNameSafe();
  15. List<Assembly> assemblies;
  16. if(!assembliesByName.TryGetValue(asmName, out assemblies)) {
  17. assembliesByName.Add(asmName, assemblies = new List<Assembly>());
  18. }
  19. assemblies.Add(asm);
  20. }
  21. public Type Resolve(SType t) {
  22. var assmeblies = Resolve(t.assemblyName);
  23. Type result = null;
  24. Exception lastException = null;
  25. for (var i = 0; i < assmeblies.Count; i++) {
  26. try {
  27. result = assmeblies[i].GetLoadedModules()[0].ResolveType(t.metadataToken);
  28. if (t.isGenericParameter) {
  29. if (!result.IsGenericTypeDefinition) {
  30. throw new SymbolResolvingFailedException(t, new ApplicationException("Generic parameter did not resolve to generic type definition"));
  31. }
  32. var genericParameters = result.GetGenericArguments();
  33. if (t.genericParameterPosition >= genericParameters.Length) {
  34. throw new SymbolResolvingFailedException(t, new ApplicationException("Generic parameter did not exist on the generic type definition"));
  35. }
  36. result = genericParameters[t.genericParameterPosition];
  37. }
  38. break;
  39. } catch(Exception ex) {
  40. lastException = ex;
  41. }
  42. }
  43. if(result == null) {
  44. throw new SymbolResolvingFailedException(t, lastException);
  45. }
  46. return result;
  47. }
  48. public FieldInfo Resolve(SField t) {
  49. var assmeblies = Resolve(t.assemblyName);
  50. FieldInfo result = null;
  51. Exception lastException = null;
  52. for (var i = 0; i < assmeblies.Count; i++) {
  53. try {
  54. result = assmeblies[i].GetLoadedModules()[0].ResolveField(t.metadataToken);
  55. break;
  56. } catch(Exception ex) {
  57. lastException = ex;
  58. }
  59. }
  60. if(result == null) {
  61. throw new SymbolResolvingFailedException(t, lastException);
  62. }
  63. return result;
  64. }
  65. public IReadOnlyList<Assembly> Resolve(string assembly) {
  66. List<Assembly> list;
  67. if(assembliesByName.TryGetValue(assembly, out list)) {
  68. return list;
  69. }
  70. return Array.Empty<Assembly>();
  71. }
  72. public MethodBase Resolve(SMethod m) {
  73. var assmeblies = Resolve(m.assemblyName);
  74. MethodBase result = null;
  75. Exception lastException = null;
  76. for (var i = 0; i < assmeblies.Count; i++) {
  77. try {
  78. result = assmeblies[i].GetLoadedModules()[0].ResolveMethod(m.metadataToken);
  79. break;
  80. } catch(Exception ex) {
  81. lastException = ex;
  82. }
  83. }
  84. if(result == null) {
  85. throw new SymbolResolvingFailedException(m, lastException);
  86. }
  87. return result;
  88. }
  89. }
  90. }
  91. #endif