Exemplo n.º 1
0
        public void Analyze(INameService nameService, ITraceService traceService, IReadOnlyList <ModuleDef> moduleDefs, ILogger logger, MethodDef method)
        {
            if (!method.HasBody)
            {
                return;
            }

            MethodTrace methodTrace = null;

            MethodTrace GetMethodTrace()
            {
                if (methodTrace == null)
                {
                    methodTrace = traceService.Trace(method);
                }
                return(methodTrace);
            }

            foreach (var instr in method.Body.Instructions)
            {
                if (instr.OpCode.Code == Code.Call && instr.Operand is IMethodDefOrRef calledMethod)
                {
                    if (calledMethod.DeclaringType.FullName == "System.Type")
                    {
                        Func <TypeDef, IEnumerable <IMemberDef> > getMember = null;
                        if (calledMethod.Name == nameof(Type.GetMethod))
                        {
                            getMember = t => t.Methods;
                        }
                        else if (calledMethod.Name == nameof(Type.GetField))
                        {
                            getMember = t => t.Fields;
                        }
                        else if (calledMethod.Name == nameof(Type.GetProperty))
                        {
                            getMember = t => t.Properties;
                        }
                        else if (calledMethod.Name == nameof(Type.GetEvent))
                        {
                            getMember = t => t.Events;
                        }
                        else if (calledMethod.Name == nameof(Type.GetMember))
                        {
                            getMember = t => Enumerable.Empty <IMemberDef>().Concat(t.Methods).Concat(t.Fields).Concat(t.Properties).Concat(t.Events);
                        }

                        if (getMember != null)
                        {
                            var trace     = GetMethodTrace();
                            var arguments = trace.TraceArguments(instr);
                            if (arguments == null)
                            {
                                logger.WarnFormat(Resources.ReflectionAnalyzer_Analyze_TracingArgumentsFailed, calledMethod.FullName, method.FullName);
                            }
                            else if (arguments.Length >= 2)
                            {
                                var types = GetReferencedTypes(method.Body.Instructions[arguments[0]], method, trace);
                                var names = GetReferencedNames(method.Body.Instructions[arguments[1]]);

                                if (!types.Any())
                                {
                                    types = moduleDefs.SelectMany(m => m.GetTypes()).ToArray();
                                }

                                foreach (var possibleMethod in types.SelectMany(getMember).Where(m => names.Contains(m.Name)))
                                {
                                    nameService.SetCanRename(possibleMethod, false);
                                }
                            }
                        }
                    }
                }
            }
        }