123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- using dnlib.DotNet;
- using HybridCLR.Editor.Meta;
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace HybridCLR.Editor.HotUpdate
- {
- public class MissingMetadataChecker
- {
- private readonly HashSet<string> _aotAssNames;
- private readonly HashSet<string> _hotUpdateAssNames;
- private readonly AssemblyCache _assCache;
- public MissingMetadataChecker(string aotDllDir, IEnumerable<string> hotUpdateAssNames)
- {
- _hotUpdateAssNames = new HashSet<string>(hotUpdateAssNames ?? new List<string>());
- _aotAssNames = new HashSet<string>();
- foreach (var aotFile in Directory.GetFiles(aotDllDir, "*.dll"))
- {
- string aotAssName = Path.GetFileNameWithoutExtension(aotFile);
- if (_hotUpdateAssNames.Contains(aotAssName))
- {
- continue;
- }
- _aotAssNames.Add(aotAssName);
- }
- _assCache = new AssemblyCache(new PathAssemblyResolver(aotDllDir));
- }
- public bool Check(string hotUpdateDllPath)
- {
- bool anyMissing = false;
- ModuleDef mod = ModuleDefMD.Load(File.ReadAllBytes(hotUpdateDllPath), _assCache.ModCtx);
- foreach (var refass in mod.GetAssemblyRefs())
- {
- string refAssName = refass.Name;
- if (_aotAssNames.Contains(refAssName))
- {
- _assCache.LoadModule(refass.Name, true);
- }
- else if (!_hotUpdateAssNames.Contains(refAssName))
- {
- UnityEngine.Debug.LogError($"Missing AOT Assembly: {refAssName}");
- anyMissing = true;
- }
- }
- foreach (TypeRef typeRef in mod.GetTypeRefs())
- {
- string defAssName = typeRef.DefinitionAssembly.Name;
- if (!_aotAssNames.Contains(defAssName))
- {
- continue;
- }
- if (typeRef.ResolveTypeDef() == null)
- {
- UnityEngine.Debug.LogError($"Missing Type: {typeRef.FullName}");
- anyMissing = true;
- }
- }
- foreach (IMethodDefOrRef memberRef in mod.GetMemberRefs())
- {
- if (memberRef.DeclaringType.DefinitionAssembly == null)
- {
- continue;
- }
- string defAssName = memberRef.DeclaringType.DefinitionAssembly.Name;
- if (!_aotAssNames.Contains(defAssName))
- {
- continue;
- }
- if (memberRef.IsField)
- {
- IField field = (IField)memberRef;
- if (field.ResolveFieldDef() == null)
- {
- UnityEngine.Debug.LogError($"Missing Field: {memberRef.FullName}");
- anyMissing = true;
- }
- }
- else if (memberRef.IsMethod)
- {
- TypeSig declaringTypeSig = memberRef.DeclaringType.ToTypeSig();
- if (memberRef.ResolveMethodDef() == null)
- {
- if (declaringTypeSig.ElementType == ElementType.Array || declaringTypeSig.ElementType == ElementType.SZArray)
- {
- continue;
- }
- UnityEngine.Debug.LogError($"Missing Method: {memberRef.FullName}");
- anyMissing = true;
- }
- }
- }
- return !anyMissing;
- }
- }
- }
|