コード例 #1
0
        private void InjectSpecializationsInMethod(MethodDefinition method,
                                                   List <SpecializationInfo> specializations)
        {
            foreach (var local in method.Body.Variables)
            {
                local.VariableType = FindSpecializedType(local.VariableType, specializations);
            }

            foreach (var instruction in method.Body.Instructions)
            {
                switch (instruction.Operand)
                {
                case TypeReference typeref:
                    instruction.Operand = FindSpecializedType(typeref, specializations);
                    break;

                case MethodReference methodref:
                    if (!(methodref.DeclaringType is GenericInstanceType genericInstanceType))
                    {
                        break;
                    }
                    var specializationArg = genericInstanceType.GenericArguments[0];
                    var newref            = _moduleDefinition.ImportReference(
                        specializations.Select(x =>
                                               x.SpecializedMethods.FirstOrDefault(y =>
                                                                                   y.Key.Resolve() == methodref.Resolve() &&
                                                                                   MetadataComparer.AreSame(specializationArg, x.Specialization))
                                               is var pair && pair.Value != null
                                        ? InsertRemainingGenerics(pair.Value, genericInstanceType)
                                        : null)
                        .FirstOrDefault(x => x != null) ?? methodref);
                    if (methodref is GenericInstanceMethod genericInstanceMethod && newref != methodref)
                    {
                        newref = newref.MakeGenericInstanceMethod(
                            genericInstanceMethod.GenericArguments
                            .Select(x => FindSpecializedType(x, specializations)).ToArray());
                    }

                    instruction.Operand = newref;
                    break;
                }
            }
        }
コード例 #2
0
        private TypeReference FindSpecializedType(TypeReference type, List <SpecializationInfo> specializations)
        {
            if (!(type is GenericInstanceType genericInstanceType) || genericInstanceType.GenericArguments.Count != 1)
            {
                return(type);
            }
            var decl = type.Resolve();

            if (specializations.SingleOrDefault(x =>
                                                x.GenericClass == decl &&
                                                MetadataComparer.AreSame(x.Specialization, genericInstanceType.GenericArguments[0])) is SpecializationInfo specialization)
            {
                return(specialization.SpecializedClass);
            }
            else
            {
                return(type);
            }
        }