コード例 #1
0
        private static TypeDefinition TryInferDeclaringTypeFromMemberAccesses(
            DevirtualisationContext context,
            VirtualisedMethod method)
        {
            // Get all private member accesses.
            var privateMemberRefs = new HashSet <IMemberReference>();

            foreach (var instruction in method.Function.Instructions.Values)
            {
                IMemberProvider provider;

                var annotation = instruction.Annotation;
                switch (annotation)
                {
                case IMemberProvider p:
                    provider = p;
                    break;

                case CallAnnotation call:
                    var resolvedMethod = context.ResolveMethod(call.Function.EntrypointAddress);
                    if (resolvedMethod == null)
                    {
                        continue;
                    }
                    provider = new ECallAnnotation(resolvedMethod, VMECallOpCode.CALL);
                    break;

                default:
                    continue;
                }

                if (provider.Member.DeclaringType != null &&
                    provider.Member.DeclaringType.ResolutionScope.GetAssembly() == context.TargetImage.Assembly &&
                    provider.RequiresSpecialAccess)
                {
                    privateMemberRefs.Add(provider.Member);
                }
            }

            var types = new List <TypeDefinition>();

            foreach (var member in privateMemberRefs)
            {
                var memberDef      = (IMemberDefinition)((IResolvable)member).Resolve();
                var declaringTypes = GetDeclaringTypes(memberDef as TypeDefinition ?? memberDef.DeclaringType);
                types.Add(declaringTypes.First(t => memberDef.IsAccessibleFromType(t)));
            }

            if (types.Count == 0)
            {
                return(null);
            }

            types.Sort((a, b) =>
            {
                if (a.IsAccessibleFromType(b))
                {
                    return(b.IsAccessibleFromType(a) ? 0 : 1);
                }
                else
                {
                    return(b.IsAccessibleFromType(a) ? 0 : -1);
                }
            });

            return(types[0]);
        }
コード例 #2
0
        private static TypeDefinition TryInferDeclaringTypeFromMemberAccesses(
            DevirtualisationContext context,
            VirtualisedMethod method)
        {
            // Get all private member accesses.
            var privateMemberRefs = new HashSet <IMemberReference>();

            foreach (var instruction in method.Function.Instructions.Values)
            {
                IMemberProvider provider;

                var annotation = instruction.Annotation;
                switch (annotation)
                {
                case IMemberProvider p:
                    provider = p;
                    break;

                case CallAnnotation call:
                    var resolvedMethod = context.ResolveMethod(call.Function.EntrypointAddress);
                    if (resolvedMethod == null)
                    {
                        continue;
                    }
                    provider = new ECallAnnotation(resolvedMethod, VMECallOpCode.CALL);
                    break;

                default:
                    continue;
                }

                if (provider.Member.DeclaringType != null &&
                    provider.Member.DeclaringType.ResolutionScope.GetAssembly() == context.TargetImage.Assembly &&
                    provider.RequiresSpecialAccess)
                {
                    privateMemberRefs.Add(provider.Member);
                }
            }

            var types = new List <TypeDefinition>();

            foreach (var member in privateMemberRefs)
            {
                var memberDef      = (IMemberDefinition)((IResolvable)member).Resolve();
                var declaringTypes = GetDeclaringTypes(memberDef as TypeDefinition ?? memberDef.DeclaringType);
                types.Add(declaringTypes.First(t => memberDef.IsAccessibleFromType(t)));
            }

            if (types.Count == 0)
            {
                return(null);
            }

            types.Sort((a, b) =>
            {
                if (a.IsAccessibleFromType(b))
                {
                    return(b.IsAccessibleFromType(a) ? 0 : 1);
                }
                else
                {
                    return(b.IsAccessibleFromType(a) ? 0 : -1);
                }
            });

            return(types[0]);

//            // Get all private member accesses.
//            var privateMemberRefs = method.Function.Instructions.Values
//                    .Select(i => i.Annotation)
//                    .OfType<IMemberProvider>()
//                    .Where(a => a.Member.DeclaringType != null
//                                && a.Member.DeclaringType.ResolutionScope == context.TargetImage.Assembly.Modules[0]
//                                && a.RequiresSpecialAccess)
//                    .Select(a => a.Member)
//                    .Distinct()
//#if DEBUG
//                    .ToArray()
//#endif
//                ;
//
//            // Get all declaring type chains.
//            var declaringTypeChains = privateMemberRefs
//                .Select(m => GetDeclaringTypes((TypeDefinition) m.DeclaringType.Resolve()))
//                .ToArray();
//
//            TypeDefinition result = null;
//
//            switch (declaringTypeChains.Length)
//            {
//                case 0:
//                    break;
//
//                case 1:
//                    result = declaringTypeChains[0][0];
//                    break;
//
//                default:
//                    // Try find common declaring type.
//                    result = GetCommonDeclaringType(declaringTypeChains);
//                    if (result == null)
//                    {
//                        // If that does not work, try looking into base types instead.
//                        var declaringTypes = privateMemberRefs
//                            .Select(m => m.DeclaringType)
//                            .ToArray();
//
//                        var helper = new TypeHelper(context.ReferenceImporter);
//                        var commonBaseType = helper.GetCommonBaseType(declaringTypes);
//                        if (commonBaseType != null &&
//                            commonBaseType.ResolutionScope == context.TargetImage.Assembly.Modules[0])
//                        {
//                            result = commonBaseType
//                                .ToTypeDefOrRef()
//                                .Resolve() as TypeDefinition;
//                        }
//                    }
//
//                    break;
//            }
//
//            return result;
        }