diff --git a/Editor/HotUpdate.meta b/Editor/HotUpdate.meta new file mode 100644 index 0000000..7b7bf3d --- /dev/null +++ b/Editor/HotUpdate.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e60a8b17b0e23a94a8ae875716208030 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/HotUpdate/MissingMetadataChecker.cs b/Editor/HotUpdate/MissingMetadataChecker.cs new file mode 100644 index 0000000..b564861 --- /dev/null +++ b/Editor/HotUpdate/MissingMetadataChecker.cs @@ -0,0 +1,96 @@ +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 _aotAssNames; + + private readonly AssemblyCache _assCache; + + public MissingMetadataChecker(string aotDllDir, IEnumerable excludeDllNames) + { + + var excludeDllNameSet = new HashSet(excludeDllNames ?? new List()); + _aotAssNames = new HashSet(); + foreach (var aotFile in Directory.GetFiles(aotDllDir, "*.dll")) + { + string aotAssName = Path.GetFileNameWithoutExtension(aotFile); + if (excludeDllNameSet.Contains(aotAssName)) + { + continue; + } + _aotAssNames.Add(aotAssName); + } + _assCache = new AssemblyCache(new PathAssemblyResolver(aotDllDir)); + } + + public bool Check(string hotUpdateDllPath) + { + 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); + } + } + + bool anyMissing = false; + + 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 methodRef in mod.GetMemberRefs()) + { + if (methodRef.DeclaringType.DefinitionAssembly == null) + { + continue; + } + string defAssName = methodRef.DeclaringType.DefinitionAssembly.Name; + if (!_aotAssNames.Contains(defAssName)) + { + continue; + } + if (methodRef.IsField) + { + + } + else if (methodRef.IsMethod) + { + TypeSig declaringTypeSig = methodRef.DeclaringType.ToTypeSig(); + if (methodRef.ResolveMethodDef() == null) + { + if (declaringTypeSig.ElementType == ElementType.Array || declaringTypeSig.ElementType == ElementType.SZArray) + { + continue; + } + UnityEngine.Debug.LogError($"Missing Method: {methodRef.FullName}"); + anyMissing = true; + } + } + } + return !anyMissing; + } + } +} diff --git a/Editor/HotUpdate/MissingMetadataChecker.cs.meta b/Editor/HotUpdate/MissingMetadataChecker.cs.meta new file mode 100644 index 0000000..bc58ca1 --- /dev/null +++ b/Editor/HotUpdate/MissingMetadataChecker.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bdd260aca2a6deb44b20210f01faa86b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: