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