[new] 新增 MissingMetadataChecker检查裁剪类型或者函数丢失的问题
parent
276cd0a4a8
commit
4b57138935
|
@ -0,0 +1,8 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e60a8b17b0e23a94a8ae875716208030
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
|
@ -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<string> _aotAssNames;
|
||||||
|
|
||||||
|
private readonly AssemblyCache _assCache;
|
||||||
|
|
||||||
|
public MissingMetadataChecker(string aotDllDir, IEnumerable<string> excludeDllNames)
|
||||||
|
{
|
||||||
|
|
||||||
|
var excludeDllNameSet = new HashSet<string>(excludeDllNames ?? new List<string>());
|
||||||
|
_aotAssNames = new HashSet<string>();
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: bdd260aca2a6deb44b20210f01faa86b
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
Loading…
Reference in New Issue