Analyzer.cs 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reflection;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using dnlib.DotNet;
  8. using HybridCLR.Editor.Meta;
  9. using UnityEditor;
  10. using IAssemblyResolver = HybridCLR.Editor.Meta.IAssemblyResolver;
  11. namespace HybridCLR.Editor.Link
  12. {
  13. public class Analyzer
  14. {
  15. private readonly IAssemblyResolver _resolver;
  16. private readonly bool _analyzeAssetType;
  17. public Analyzer(IAssemblyResolver resolver, bool analyzeAssetType)
  18. {
  19. _resolver = resolver;
  20. _analyzeAssetType = analyzeAssetType;
  21. }
  22. public HashSet<TypeRef> CollectRefs(List<string> rootAssemblies)
  23. {
  24. using (var assCollector = new AssemblyCache(_resolver))
  25. {
  26. var rootAssemblyNames = new HashSet<string>(rootAssemblies);
  27. var typeRefs = new HashSet<TypeRef>(TypeEqualityComparer.Instance);
  28. foreach (var rootAss in rootAssemblies)
  29. {
  30. var dnAss = assCollector.LoadModule(rootAss, _analyzeAssetType);
  31. foreach (var type in dnAss.GetTypeRefs())
  32. {
  33. if (!rootAssemblyNames.Contains(type.DefinitionAssembly.Name.ToString()))
  34. {
  35. typeRefs.Add(type);
  36. }
  37. }
  38. }
  39. if (_analyzeAssetType)
  40. {
  41. var modsExludeRoots = assCollector.LoadedModules
  42. .Where(e => !rootAssemblyNames.Contains(e.Key))
  43. .ToDictionary(e => e.Key, e => e.Value);
  44. CollectObjectTypeInAssets(modsExludeRoots, typeRefs);
  45. }
  46. assCollector.Dispose();
  47. return typeRefs;
  48. }
  49. }
  50. public void CollectObjectTypeInAssets(Dictionary<string, ModuleDefMD> mods, HashSet<TypeRef> typeRefs)
  51. {
  52. var objTypes = new HashSet<Type>();
  53. string[] guids = AssetDatabase.FindAssets("t:Object", new[] { "Assets" });
  54. foreach (string guid in guids)
  55. {
  56. string assetPath = AssetDatabase.GUIDToAssetPath(guid);
  57. Type mainAssetType = AssetDatabase.GetMainAssetTypeAtPath(assetPath);
  58. if (mainAssetType == typeof(SceneAsset))
  59. {
  60. }
  61. else
  62. {
  63. UnityEngine.Object[] objs = AssetDatabase.LoadAllAssetsAtPath(assetPath);
  64. foreach (UnityEngine.Object obj in objs)
  65. {
  66. if (obj != null)
  67. {
  68. objTypes.Add(obj.GetType());
  69. }
  70. }
  71. }
  72. }
  73. var importers = mods.ToDictionary(e => e.Key, e => new Importer(e.Value));
  74. //Debug.Log($"importers count:{importers.Count} importers:{string.Join(",", importers.Keys)}");
  75. foreach (var type in objTypes)
  76. {
  77. if (importers.TryGetValue(type.Assembly.GetName().Name, out var im))
  78. {
  79. typeRefs.Add((TypeRef)im.Import(type));
  80. //Debug.Log($"== add asset type:{type}");
  81. }
  82. else
  83. {
  84. //Debug.Log($"== ignore asset type:{type} {type.Assembly.GetName().Name}");
  85. }
  86. }
  87. }
  88. }
  89. }