| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 | 
							- using dnlib.DotNet;
 
- using HybridCLR.Editor.ABI;
 
- using HybridCLR.Editor.Meta;
 
- using System;
 
- using System.Collections.Generic;
 
- using System.Linq;
 
- using System.Text;
 
- using System.Threading.Tasks;
 
- using UnityEngine;
 
- namespace HybridCLR.Editor.MethodBridge
 
- {
 
-     public class Analyzer
 
-     {
 
-         public class Options
 
-         {
 
-             public AssemblyReferenceDeepCollector Collector { get; set; }
 
-             public int MaxIterationCount { get; set; }
 
-         }
 
-         private readonly int _maxInterationCount;
 
-         private readonly AssemblyReferenceDeepCollector _assemblyCollector;
 
-         private readonly object _lock = new object();
 
-         private readonly List<TypeDef> _typeDefs = new List<TypeDef>();
 
-         private readonly HashSet<GenericClass> _genericTypes = new HashSet<GenericClass>();
 
-         private readonly HashSet<GenericMethod> _genericMethods = new HashSet<GenericMethod>();
 
-         private List<GenericMethod> _processingMethods = new List<GenericMethod>();
 
-         private List<GenericMethod> _newMethods = new List<GenericMethod>();
 
-         public IReadOnlyList<TypeDef> TypeDefs => _typeDefs;
 
-         public IReadOnlyCollection<GenericClass> GenericTypes => _genericTypes;
 
-         public IReadOnlyCollection<GenericMethod> GenericMethods => _genericMethods;
 
-         private readonly MethodReferenceAnalyzer _methodReferenceAnalyzer;
 
-         public Analyzer(Options options)
 
-         {
 
-             _maxInterationCount = options.MaxIterationCount;
 
-             _assemblyCollector = options.Collector;
 
-             _methodReferenceAnalyzer = new MethodReferenceAnalyzer(this.OnNewMethod);
 
-         }
 
-         private void TryAddAndWalkGenericType(GenericClass gc)
 
-         {
 
-             if (gc == null)
 
-             {
 
-                 return;
 
-             }
 
-             lock(_lock)
 
-             {
 
-                 gc = StandardizeClass(gc);
 
-                 if (_genericTypes.Add(gc))
 
-                 {
 
-                     WalkType(gc);
 
-                 }
 
-             }
 
-         }
 
-         private GenericClass StandardizeClass(GenericClass gc)
 
-         {
 
-             TypeDef typeDef = gc.Type;
 
-             ICorLibTypes corLibTypes = typeDef.Module.CorLibTypes;
 
-             List<TypeSig> klassGenericParams = gc.KlassInst != null ? MetaUtil.ToShareTypeSigs(corLibTypes, gc.KlassInst) : (typeDef.GenericParameters.Count > 0 ? MetaUtil.CreateDefaultGenericParams(typeDef.Module, typeDef.GenericParameters.Count) : null);
 
-             return new GenericClass(typeDef, klassGenericParams);
 
-         }
 
-         private GenericMethod StandardizeMethod(GenericMethod gm)
 
-         {
 
-             TypeDef typeDef = gm.Method.DeclaringType;
 
-             ICorLibTypes corLibTypes = typeDef.Module.CorLibTypes;
 
-             List<TypeSig> klassGenericParams = gm.KlassInst != null ? MetaUtil.ToShareTypeSigs(corLibTypes, gm.KlassInst) : (typeDef.GenericParameters.Count > 0 ? MetaUtil.CreateDefaultGenericParams(typeDef.Module, typeDef.GenericParameters.Count) : null);
 
-             List<TypeSig> methodGenericParams = gm.MethodInst != null ? MetaUtil.ToShareTypeSigs(corLibTypes, gm.MethodInst) : (gm.Method.GenericParameters.Count > 0 ? MetaUtil.CreateDefaultGenericParams(typeDef.Module, gm.Method.GenericParameters.Count) : null);
 
-             return new GenericMethod(gm.Method, klassGenericParams, methodGenericParams);
 
-         }
 
-         private void OnNewMethod(MethodDef methodDef, List<TypeSig> klassGenericInst, List<TypeSig> methodGenericInst, GenericMethod method)
 
-         {
 
-             lock(_lock)
 
-             {
 
-                 method = StandardizeMethod(method);
 
-                 if (_genericMethods.Add(method))
 
-                 {
 
-                     _newMethods.Add(method);
 
-                 }
 
-                 if (method.KlassInst != null)
 
-                 {
 
-                     TryAddAndWalkGenericType(new GenericClass(method.Method.DeclaringType, method.KlassInst));
 
-                 }
 
-             }
 
-         }
 
-         private void WalkType(GenericClass gc)
 
-         {
 
-             //Debug.Log($"typespec:{sig} {sig.GenericType} {sig.GenericType.TypeDefOrRef.ResolveTypeDef()}");
 
-             //Debug.Log($"== walk generic type:{new GenericInstSig(gc.Type.ToTypeSig().ToClassOrValueTypeSig(), gc.KlassInst)}");
 
-             ITypeDefOrRef baseType = gc.Type.BaseType;
 
-             if (baseType != null && baseType.TryGetGenericInstSig() != null)
 
-             {
 
-                 GenericClass parentType = GenericClass.ResolveClass((TypeSpec)baseType, new GenericArgumentContext(gc.KlassInst, null));
 
-                 TryAddAndWalkGenericType(parentType);
 
-             }
 
-             foreach (var method in gc.Type.Methods)
 
-             {
 
-                 var gm = StandardizeMethod(new GenericMethod(method, gc.KlassInst, null));
 
-                 //Debug.Log($"add method:{gm.Method} {gm.KlassInst}");
 
-                 
 
-                 if (_genericMethods.Add(gm))
 
-                 {
 
-                     if (method.HasBody && method.Body.Instructions != null)
 
-                     {
 
-                         _newMethods.Add(gm);
 
-                     }
 
-                 }
 
-             }
 
-         }
 
-         private void WalkType(TypeDef typeDef)
 
-         {
 
-             _typeDefs.Add(typeDef);
 
-             ITypeDefOrRef baseType = typeDef.BaseType;
 
-             if (baseType != null && baseType.TryGetGenericInstSig() != null)
 
-             {
 
-                 GenericClass gc = GenericClass.ResolveClass((TypeSpec)baseType, null);
 
-                 TryAddAndWalkGenericType(gc);
 
-             }
 
-             foreach (var method in typeDef.Methods)
 
-             {
 
-                 // 对于带泛型的参数,统一泛型共享为object
 
-                 var gm = StandardizeMethod(new GenericMethod(method, null, null));
 
-                 _genericMethods.Add(gm);
 
-             }
 
-         }
 
-         private void Prepare()
 
-         {
 
-             // 将所有非泛型函数全部加入函数列表,同时立马walk这些method。
 
-             // 后续迭代中将只遍历MethodSpec
 
-             foreach (var ass in _assemblyCollector.GetLoadedModules())
 
-             {
 
-                 foreach (TypeDef typeDef in ass.GetTypes())
 
-                 {
 
-                     WalkType(typeDef);
 
-                 }
 
-                 for (uint rid = 1, n = ass.Metadata.TablesStream.TypeSpecTable.Rows; rid <= n; rid++)
 
-                 {
 
-                     var ts = ass.ResolveTypeSpec(rid);
 
-                     var cs = GenericClass.ResolveClass(ts, null);
 
-                     if (cs != null)
 
-                     {
 
-                         TryAddAndWalkGenericType(cs);
 
-                     }
 
-                 }
 
-                 for (uint rid = 1, n = ass.Metadata.TablesStream.MethodSpecTable.Rows; rid <= n; rid++)
 
-                 {
 
-                     var ms = ass.ResolveMethodSpec(rid);
 
-                     var gm = GenericMethod.ResolveMethod(ms, null)?.ToGenericShare();
 
-                     if (gm == null)
 
-                     {
 
-                         continue;
 
-                     }
 
-                     gm = StandardizeMethod(gm);
 
-                     if (_genericMethods.Add(gm))
 
-                     {
 
-                         _newMethods.Add(gm);
 
-                     }
 
-                 }
 
-             }
 
-             Debug.Log($"PostPrepare allMethods:{_genericMethods.Count} newMethods:{_newMethods.Count}");
 
-         }
 
-         private void RecursiveCollect()
 
-         {
 
-             for (int i = 0; i < _maxInterationCount && _newMethods.Count > 0; i++)
 
-             {
 
-                 var temp = _processingMethods;
 
-                 _processingMethods = _newMethods;
 
-                 _newMethods = temp;
 
-                 _newMethods.Clear();
 
-                 Task.WaitAll(_processingMethods.Select(method => Task.Run(() =>
 
-                 {
 
-                     _methodReferenceAnalyzer.WalkMethod(method.Method, method.KlassInst, method.MethodInst);
 
-                 })).ToArray());
 
-                 Debug.Log($"iteration:[{i}] genericClass:{_genericTypes.Count} genericMethods:{_genericMethods.Count} newMethods:{_newMethods.Count}");
 
-             }
 
-         }
 
-         public void Run()
 
-         {
 
-             Prepare();
 
-             RecursiveCollect();
 
-         }
 
-     }
 
- }
 
 
  |