Beispiel #1
0
        public void Audit(Action <ProjectIssue> onIssueFound, Action onComplete, IProgressBar progressBar = null)
        {
            if (m_ProblemDescriptors == null)
            {
                throw new Exception("Issue Database not initialized.");
            }

            if (m_Config.AnalyzeInBackground && m_AssemblyAnalysisThread != null)
            {
                m_AssemblyAnalysisThread.Join();
            }

            var compilationPipeline = new AssemblyCompilationPipeline
            {
                AssemblyCompilationFinished = (assemblyName, compilerMessages) => ProcessCompilerMessages(assemblyName, compilerMessages, onIssueFound)
            };

            Profiler.BeginSample("ScriptAuditor.Audit.Compilation");
            var assemblyInfos = compilationPipeline.Compile(m_Config.AnalyzeEditorCode, progressBar);

            Profiler.EndSample();

            var callCrawler           = new CallCrawler();
            var issues                = new List <ProjectIssue>();
            var localAssemblyInfos    = assemblyInfos.Where(info => !info.readOnly).ToArray();
            var readOnlyAssemblyInfos = assemblyInfos.Where(info => info.readOnly).ToArray();

            var assemblyDirectories = new List <string>();

            assemblyDirectories.AddRange(AssemblyInfoProvider.GetPrecompiledAssemblyDirectories(PrecompiledAssemblyTypes.UserAssembly | PrecompiledAssemblyTypes.UnityEngine));
            if (m_Config.AnalyzeEditorCode)
            {
                assemblyDirectories.AddRange(AssemblyInfoProvider.GetPrecompiledAssemblyDirectories(PrecompiledAssemblyTypes.UnityEditor));
            }

            var onCallFound = new Action <CallInfo>(pair =>
            {
                callCrawler.Add(pair);
            });

            var onCompleteInternal = new Action <IProgressBar>(bar =>
            {
                compilationPipeline.Dispose();
                callCrawler.BuildCallHierarchies(issues, bar);
                onComplete();
            });

            var onIssueFoundInternal = new Action <ProjectIssue>(issue =>
            {
                if (issue.category == IssueCategory.Code)
                {
                    issues.Add(issue);
                }
                onIssueFound(issue);
            });

            Profiler.BeginSample("ScriptAuditor.Audit.Analysis");

            // first phase: analyze assemblies generated from editable scripts
            AnalyzeAssemblies(localAssemblyInfos, assemblyDirectories, onCallFound, onIssueFoundInternal, null, progressBar);

            var enableBackgroundAnalysis = m_Config.AnalyzeInBackground;

#if !UNITY_2019_3_OR_NEWER
            enableBackgroundAnalysis = false;
#endif
            // second phase: analyze all remaining assemblies, in a separate thread if enableBackgroundAnalysis is enabled
            if (enableBackgroundAnalysis)
            {
                m_AssemblyAnalysisThread = new Thread(() =>
                                                      AnalyzeAssemblies(readOnlyAssemblyInfos, assemblyDirectories, onCallFound, onIssueFoundInternal, onCompleteInternal));
                m_AssemblyAnalysisThread.Name     = "Assembly Analysis";
                m_AssemblyAnalysisThread.Priority = ThreadPriority.BelowNormal;
                m_AssemblyAnalysisThread.Start();
            }
            else
            {
                Profiler.BeginSample("ScriptAuditor.Audit.AnalysisReadOnly");
                AnalyzeAssemblies(readOnlyAssemblyInfos, assemblyDirectories, onCallFound, onIssueFoundInternal, onCompleteInternal, progressBar);
                Profiler.EndSample();
            }
            Profiler.EndSample();
        }
        public void Audit(Action <ProjectIssue> onIssueFound, Action onComplete, IProgressBar progressBar = null)
        {
            if (m_Config.AnalyzeInBackground && m_AssemblyAnalysisThread != null)
            {
                m_AssemblyAnalysisThread.Join();
            }

            var compilationHelper = new AssemblyCompilationHelper();
            var callCrawler       = new CallCrawler();

            Profiler.BeginSample("ScriptAuditor.Audit.Compilation");
            var assemblyInfos = compilationHelper.Compile(progressBar);

            Profiler.EndSample();

            var issues                = new List <ProjectIssue>();
            var localAssemblyInfos    = assemblyInfos.Where(info => !info.readOnly).ToArray();
            var readOnlyAssemblyInfos = assemblyInfos.Where(info => info.readOnly).ToArray();

            var assemblyDirectories = new List <string>();

            assemblyDirectories.AddRange(AssemblyHelper.GetPrecompiledAssemblyDirectories());
            assemblyDirectories.AddRange(AssemblyHelper.GetPrecompiledEngineAssemblyDirectories());

            var onCallFound = new Action <CallInfo>(pair =>
            {
                callCrawler.Add(pair);
            });

            var onCompleteInternal = new Action <IProgressBar>(bar =>
            {
                compilationHelper.Dispose();
                callCrawler.BuildCallHierarchies(issues, bar);
                onComplete();
            });

            var onIssueFoundInternal = new Action <ProjectIssue>(issue =>
            {
                issues.Add(issue);
                onIssueFound(issue);
            });

            Profiler.BeginSample("ScriptAuditor.Audit.Analysis");

            // first phase: analyze assemblies generated from editable scripts
            AnalyzeAssemblies(localAssemblyInfos, assemblyDirectories, onCallFound, onIssueFoundInternal, null, progressBar);

            var enableBackgroundAnalysis = m_Config.AnalyzeInBackground;

#if !UNITY_2019_3_OR_NEWER
            enableBackgroundAnalysis = false;
#endif
            // second phase: analyze all remaining assemblies, in a separate thread if enableBackgroundAnalysis is enabled
            if (enableBackgroundAnalysis)
            {
                m_AssemblyAnalysisThread = new Thread(() =>
                                                      AnalyzeAssemblies(readOnlyAssemblyInfos, assemblyDirectories, onCallFound, onIssueFound, onCompleteInternal));
                m_AssemblyAnalysisThread.Name     = "Assembly Analysis";
                m_AssemblyAnalysisThread.Priority = ThreadPriority.BelowNormal;
                m_AssemblyAnalysisThread.Start();
            }
            else
            {
                Profiler.BeginSample("ScriptAuditor.Audit.AnalysisReadOnly");
                AnalyzeAssemblies(readOnlyAssemblyInfos, assemblyDirectories, onCallFound, onIssueFoundInternal, onCompleteInternal, progressBar);
                Profiler.EndSample();
            }
            Profiler.EndSample();
        }