Пример #1
0
        void SearchAndEval(ProblemDescriptor p, System.Reflection.Assembly[] assemblies, ProjectReport projectReport)
        {
            if (string.IsNullOrEmpty(p.customevaluator))
            {
                // try all assemblies. Need to find a way to only evaluate on the right assembly
                foreach (var assembly in assemblies)
                {
                    try
                    {
                        var value = MethodEvaluator.Eval(assembly.Location,
                                                         p.type, "get_" + p.method, new System.Type[0] {
                        }, new object[0] {
                        });

                        if (value.ToString() == p.value)
                        {
                            projectReport.AddIssue(new ProjectIssue
                            {
                                description = p.description,
                                category    = IssueCategory.ProjectSettings,
                                descriptor  = p
                            });

                            // stop iterating assemblies
                            break;
                        }
                    }
                    catch (Exception)
                    {
                        // this is safe to ignore
                    }
                }
            }
            else
            {
                Type       helperType = m_Helpers.GetType();
                MethodInfo theMethod  = helperType.GetMethod(p.customevaluator);
                bool       isIssue    = (bool)theMethod.Invoke(m_Helpers, null);

                if (isIssue)
                {
                    projectReport.AddIssue(new ProjectIssue
                    {
                        description = p.description,
                        category    = IssueCategory.ProjectSettings,
                        descriptor  = p
                    });
                }
            }
        }
Пример #2
0
        private void AnalyzeMethodBody(ProjectReport projectReport, AssemblyDefinition a, MethodDefinition caller, CallCrawler callCrawler)
        {
            if (!caller.DebugInformation.HasSequencePoints)
            {
                return;
            }

            var callerNode = new CallTreeNode(caller);

            foreach (var inst in caller.Body.Instructions.Where(i => m_OpCodes.Contains(i.OpCode)))
            {
                //var msg = string.Empty;
                SequencePoint s = null;
                for (var i = inst; i != null; i = i.Previous)
                {
                    s = caller.DebugInformation.GetSequencePoint(i);
                    if (s != null)
                    {
                        // msg = i == inst ? " exactly" : "nearby";
                        break;
                    }
                }

                var location = callerNode.location = new Location
                {
                    path = s.Document.Url.Replace("\\", "/"), line = s.StartLine
                };

                if (inst.OpCode == OpCodes.Call || inst.OpCode == OpCodes.Callvirt)
                {
                    callCrawler.Add(caller, (MethodReference)inst.Operand, location);
                }

                foreach (var analyzer in m_InstructionAnalyzers)
                {
                    if (analyzer.GetOpCodes().Contains(inst.OpCode))
                    {
                        var projectIssue = analyzer.Analyze(caller, inst);
                        if (projectIssue != null)
                        {
                            projectIssue.callTree.AddChild(callerNode);
                            projectIssue.location = location;
                            projectIssue.assembly = a.Name.Name;

                            projectReport.AddIssue(projectIssue);
                        }
                    }
                }
            }
        }
Пример #3
0
        private void AddIssue(ProblemDescriptor descriptor, string description, ProjectReport projectReport)
        {
            string projectWindowPath = "";
            var    mappings          = m_ProjectSettingsMapping.Where(p => p.Key.Contains(descriptor.type));

            if (mappings.Count() > 0)
            {
                projectWindowPath = mappings.First().Value;
            }
            projectReport.AddIssue(new ProjectIssue
                                   (
                                       descriptor,
                                       description = description,
                                       IssueCategory.ProjectSettings,
                                       new Location {
                path = projectWindowPath
            }
                                   ));
        }
        private void Analyze()
        {
            m_ShouldRefresh = true;
            m_AnalysisState = AnalysisState.InProgress;
            m_ProjectReport = new ProjectReport();
            foreach (var view in m_AnalysisViews)
            {
                view.m_Table.Reset();
            }

            var newIssues = new List <ProjectIssue>();

            try
            {
                m_ProjectAuditor.Audit((projectIssue) =>
                {
                    newIssues.Add(projectIssue);
                    m_ProjectReport.AddIssue(projectIssue);
                },
                                       (bool completed) =>
                {
                    // add batch of issues
                    foreach (var view in m_AnalysisViews)
                    {
                        view.AddIssues(newIssues);
                    }
                    newIssues.Clear();

                    if (completed)
                    {
                        m_AnalysisState = AnalysisState.Completed;
                    }
                    m_ShouldRefresh = true;
                },
                                       new ProgressBarDisplay());
            }
            catch (AssemblyCompilationException e)
            {
                m_AnalysisState = AnalysisState.NotStarted;
                Debug.LogError(e);
            }
        }
Пример #5
0
        private void AnalyzeAssembly(string assemblyPath, ProjectReport projectReport)
        {
            using (var a = AssemblyDefinition.ReadAssembly(assemblyPath, new ReaderParameters()
            {
                ReadSymbols = true
            }))
            {
                foreach (var m in a.MainModule.Types.SelectMany(t => t.Methods))
                {
                    if (!m.HasBody)
                    {
                        continue;
                    }

                    List <ProjectIssue> methodBobyIssues = new List <ProjectIssue>();

                    foreach (var inst in m.Body.Instructions.Where(i =>
                                                                   (i.OpCode == OpCodes.Call || i.OpCode == OpCodes.Callvirt)))
                    {
                        var calledMethod = ((MethodReference)inst.Operand);

                        // HACK: need to figure out a way to know whether a method is actually a property
                        var p = m_ProblemDescriptors.SingleOrDefault(c => c.type == calledMethod.DeclaringType.FullName &&
                                                                     (c.method == calledMethod.Name ||
                                                                      ("get_" + c.method) == calledMethod.Name));

                        if (p == null)
                        {
                            // Are we trying to warn about a whole namespace?
                            p = m_ProblemDescriptors.SingleOrDefault(c =>
                                                                     c.type == calledMethod.DeclaringType.Namespace && c.method == "*");
                        }

                        //if (p.type != null && m.HasCustomDebugInformations)
                        if (p != null && m.DebugInformation.HasSequencePoints)
                        {
                            //var msg = string.Empty;
                            SequencePoint s = null;
                            for (var i = inst; i != null; i = i.Previous)
                            {
                                s = m.DebugInformation.GetSequencePoint(i);
                                if (s != null)
                                {
                                    // msg = i == inst ? " exactly" : "nearby";
                                    break;
                                }
                            }

                            if (s != null)
                            {
                                // Ignore whitelisted packages
                                // (SteveM - I'd put this code further up in one of the outer loops but I don't
                                // know if it's possible to get the URL further up to compare with the whitelist)
                                bool isPackageWhitelisted = false;
                                foreach (string package in m_WhitelistedPackages)
                                {
                                    if (s.Document.Url.Contains(package))
                                    {
                                        isPackageWhitelisted = true;
                                        break;
                                    }
                                }

                                if (!isPackageWhitelisted)
                                {
                                    var description = p.description;
                                    if (description.Contains(".*"))
                                    {
                                        description = calledMethod.DeclaringType.FullName + "::" + calledMethod.Name;
                                    }

                                    // do not add the same type of issue again (for example multiple Linq instructions)
                                    var foundIssues = methodBobyIssues.Where(i =>
                                                                             i.descriptor == p && i.line == s.StartLine &&
                                                                             i.column == s.StartColumn);
                                    if (foundIssues.FirstOrDefault() == null)
                                    {
                                        var projectIssue = new ProjectIssue
                                        {
                                            description   = description,
                                            category      = IssueCategory.ApiCalls,
                                            descriptor    = p,
                                            callingMethod = m.FullName,
                                            url           = s.Document.Url.Replace("\\", "/"),
                                            line          = s.StartLine,
                                            column        = s.StartColumn
                                        };
                                        projectReport.AddIssue(projectIssue);
                                        methodBobyIssues.Add(projectIssue);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }