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]); }
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; }