public void Audit(ProjectReport projectReport, IProgressBar progressBar = null) { var userAssemblies = GetPlayerAssemblies(); if (userAssemblies.Count > 0) { m_AssemblyResolver = new DefaultAssemblyResolver(); #if UNITY_2019_1_OR_NEWER List <string> assemblyPaths = new List <string>(); assemblyPaths.AddRange(CompilationPipeline.GetPrecompiledAssemblyPaths(CompilationPipeline.PrecompiledAssemblySources .UserAssembly)); assemblyPaths.AddRange(CompilationPipeline.GetPrecompiledAssemblyPaths(CompilationPipeline.PrecompiledAssemblySources .UnityEngine)); foreach (var dir in assemblyPaths.Select(path => Path.GetDirectoryName(path)).Distinct()) { m_AssemblyResolver.AddSearchDirectory(dir); } #else m_AssemblyResolver.AddSearchDirectory(Path.Combine(EditorApplication.applicationContentsPath, "Managed", "UnityEngine")); #endif m_AssemblyResolver.AddSearchDirectory(Path.Combine(EditorApplication.applicationContentsPath, "UnityExtensions", "Unity", "GUISystem")); foreach (var dir in userAssemblies.Select(path => Path.GetDirectoryName(path)).Distinct()) { m_AssemblyResolver.AddSearchDirectory(dir); } var callCrawler = new CallCrawler(); if (progressBar != null) { progressBar.Initialize("Analyzing Scripts", "Analyzing project scripts", m_PlayerAssemblies.Length); } // Analyse all Player assemblies, including Package assemblies. foreach (var assemblyPath in userAssemblies) { if (progressBar != null) { progressBar.AdvanceProgressBar(string.Format("Analyzing {0} scripts", Path.GetFileName(assemblyPath))); } if (!File.Exists(assemblyPath)) { Debug.LogError(assemblyPath + " not found."); continue; } AnalyzeAssembly(assemblyPath, projectReport, callCrawler); } if (progressBar != null) { progressBar.ClearProgressBar(); } callCrawler.BuildCallHierarchies(projectReport, progressBar); } }
public void Audit(ProjectReport projectReport, IProgressBar progressBar = null) { if (!AssemblyHelper.CompileAssemblies()) { return; } var callCrawler = new CallCrawler(); using (var assemblyResolver = new DefaultAssemblyResolver()) { var compiledAssemblyPaths = AssemblyHelper.GetCompiledAssemblyPaths(); foreach (var dir in AssemblyHelper.GetPrecompiledAssemblyDirectories()) { assemblyResolver.AddSearchDirectory(dir); } foreach (var dir in AssemblyHelper.GetPrecompiledEngineAssemblyDirectories()) { assemblyResolver.AddSearchDirectory(dir); } foreach (var dir in AssemblyHelper.GetCompiledAssemblyDirectories()) { assemblyResolver.AddSearchDirectory(dir); } if (progressBar != null) { progressBar.Initialize("Analyzing Scripts", "Analyzing project scripts", m_PlayerAssemblies.Length); } // Analyse all Player assemblies, including Package assemblies. foreach (var assemblyPath in compiledAssemblyPaths) { if (progressBar != null) { progressBar.AdvanceProgressBar(string.Format("Analyzing {0} scripts", Path.GetFileName(assemblyPath))); } if (!File.Exists(assemblyPath)) { Debug.LogError(assemblyPath + " not found."); continue; } AnalyzeAssembly(assemblyPath, assemblyResolver, projectReport, callCrawler); } } if (progressBar != null) { progressBar.ClearProgressBar(); } callCrawler.BuildCallHierarchies(projectReport, progressBar); }
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); } } } } }
private void AnalyzeAssembly(string assemblyPath, IAssemblyResolver assemblyResolver, ProjectReport projectReport, CallCrawler callCrawler) { using (var a = AssemblyDefinition.ReadAssembly(assemblyPath, new ReaderParameters() { ReadSymbols = true, AssemblyResolver = assemblyResolver })) { foreach (var methodDefinition in MonoCecilHelper.AggregateAllTypeDefinitions(a.MainModule.Types).SelectMany(t => t.Methods)) { if (!methodDefinition.HasBody) { continue; } AnalyzeMethodBody(projectReport, a, methodDefinition, callCrawler); } } }