三国卡牌客户端基础资源仓库
hch
8 小时以前 0a840e0a483327f8522e60349f5fc848ff4d88a0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
using dnlib.DotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
 
namespace HybridCLR.Editor.Meta
{
    public class GenericMethod
    {
        public MethodDef Method { get; }
 
        public List<TypeSig> KlassInst { get; }
 
        public List<TypeSig> MethodInst { get; }
 
        private readonly int _hashCode;
 
        public GenericMethod(MethodDef method, List<TypeSig> classInst, List<TypeSig> methodInst)
        {
            Method = method;
            KlassInst = classInst;
            MethodInst = methodInst;
            _hashCode = ComputHashCode();
        }
 
        public GenericMethod ToGenericShare()
        {
            ICorLibTypes corLibTypes = Method.Module.CorLibTypes;
            return new GenericMethod(Method, MetaUtil.ToShareTypeSigs(corLibTypes, KlassInst), MetaUtil.ToShareTypeSigs(corLibTypes, MethodInst));
        }
 
        public override bool Equals(object obj)
        {
            GenericMethod o = (GenericMethod)obj;
            return Method == o.Method
                && MetaUtil.EqualsTypeSigArray(KlassInst, o.KlassInst)
                && MetaUtil.EqualsTypeSigArray(MethodInst, o.MethodInst);
        }
 
        public override int GetHashCode()
        {
            return _hashCode;
        }
 
        public override string ToString()
        {
            return $"{Method}|{string.Join(",", (IEnumerable<TypeSig>)KlassInst ?? Array.Empty<TypeSig>())}|{string.Join(",", (IEnumerable<TypeSig>)MethodInst ?? Array.Empty<TypeSig>())}";
        }
 
        private int ComputHashCode()
        {
            int hash = MethodEqualityComparer.CompareDeclaringTypes.GetHashCode(Method);
            if (KlassInst != null)
            {
                hash = HashUtil.CombineHash(hash, HashUtil.ComputHash(KlassInst));
            }
            if (MethodInst != null)
            {
                hash = HashUtil.CombineHash(hash, HashUtil.ComputHash(MethodInst));
            }
            return hash;
        }
 
        public MethodSpec ToMethodSpec()
        {
            IMethodDefOrRef mt = KlassInst != null ? 
                (IMethodDefOrRef)new MemberRefUser(this.Method.Module, Method.Name, Method.MethodSig, new TypeSpecUser(new GenericInstSig(this.Method.DeclaringType.ToTypeSig().ToClassOrValueTypeSig(), this.KlassInst)))
                : this.Method;
            return new MethodSpecUser(mt, new GenericInstMethodSig(MethodInst));
        }
 
        public static GenericMethod ResolveMethod(IMethod method, GenericArgumentContext ctx)
        {
            //Debug.Log($"== resolve method:{method}");
            TypeDef typeDef = null;
            List<TypeSig> klassInst = null;
            List<TypeSig> methodInst = null;
 
            MethodDef methodDef = null;
 
 
            var decalringType = method.DeclaringType;
            typeDef = decalringType.ResolveTypeDef();
            if (typeDef == null)
            {
                return null;
            }
            GenericInstSig gis = decalringType.TryGetGenericInstSig();
            if (gis != null)
            {
                klassInst = ctx != null ? gis.GenericArguments.Select(ga => MetaUtil.Inflate(ga, ctx)).ToList() : gis.GenericArguments.ToList();
            }
            methodDef = method.ResolveMethodDef();
            if (methodDef == null)
            {
                Debug.LogWarning($"method:{method} ResolveMethodDef() == null");
                return null;
            }
            if (method is MethodSpec methodSpec)
            {
                methodInst = ctx != null ? methodSpec.GenericInstMethodSig.GenericArguments.Select(ga => MetaUtil.Inflate(ga, ctx)).ToList()
                    : methodSpec.GenericInstMethodSig.GenericArguments.ToList();
            }
            return new GenericMethod(methodDef, klassInst, methodInst);
        }
 
    }
}