BackgroundAnalyzer.cs 3.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. using System.IO;
  2. using System.Linq;
  3. using System.Collections.Generic;
  4. using IntelligentProjectAnalyzer.Analyzer;
  5. // All using statements now refer to the new data-only class
  6. using static IntelligentProjectAnalyzer.Editor.DependencyBuilderData;
  7. namespace IntelligentProjectAnalyzer.Editor
  8. {
  9. /// <summary>
  10. /// Executes the CPU-intensive analysis on a background thread to avoid freezing the editor.
  11. /// </summary>
  12. public static class BackgroundAnalyzer
  13. {
  14. /// <summary>
  15. /// Runs the full dependency analysis on a collection of assets.
  16. /// </summary>
  17. /// <param name="allMetadata">A list containing metadata for all assets to be analyzed.</param>
  18. /// <param name="roslynSetupData">The setup data required for Roslyn analysis.</param>
  19. /// <returns>A list of analysis results, one for each processed asset.</returns>
  20. public static List<AssetMetadata> RunAnalysis(List<AssetMetadata> allMetadata, RoslynSetupData roslynSetupData)
  21. {
  22. // Initialize the Roslyn analyzer with all the necessary data.
  23. var roslynAnalyzer = new RoslynTypeDependencyAnalyzer(roslynSetupData.SourceFiles, roslynSetupData.References, roslynSetupData.PreprocessorSymbols, roslynSetupData.SystemTypePrefixes);
  24. // --- IMPORTANT ---
  25. // First, run analysis on ALL script types to build the complete, internal dependency tree in the analyzer.
  26. var allScriptTypes = roslynAnalyzer.TypeToPathMap.Keys;
  27. roslynAnalyzer.AnalyzeTypeDependenciesForFile(allScriptTypes);
  28. // Now, iterate through our assets and populate the script dependencies.
  29. foreach (var metadata in allMetadata)
  30. {
  31. // We only need to run Roslyn analysis for scripts.
  32. // Prefabs and SOs have their direct dependencies already.
  33. if (metadata is ScriptMetadata scriptMetadata)
  34. {
  35. ProcessScript(scriptMetadata, roslynAnalyzer, roslynSetupData.TypeToGuidMap);
  36. }
  37. }
  38. return allMetadata;
  39. }
  40. /// <summary>
  41. /// Processes a single script to find all its recursive dependencies.
  42. /// </summary>
  43. private static void ProcessScript(ScriptMetadata metadata, RoslynTypeDependencyAnalyzer analyzer, IReadOnlyDictionary<string, string> typeToGuidMap)
  44. {
  45. // Get all types defined within this specific script file.
  46. var typesInFile = analyzer.TypeToPathMap
  47. .Where(pair => Path.GetFullPath(pair.Value).Replace('\\', '/') == metadata.FullPath)
  48. .Select(pair => pair.Key);
  49. var allDependenciesInFile = new HashSet<string>();
  50. foreach (var typeName in typesInFile)
  51. {
  52. // For each type, get its complete, recursive list of dependencies from the analyzer's pre-built tree.
  53. var dependenciesForType = analyzer.GetRecursiveDependencies(typeName);
  54. foreach (var dep in dependenciesForType)
  55. {
  56. allDependenciesInFile.Add(dep);
  57. }
  58. }
  59. // Now, convert the dependency type names back to GUIDs and add them to the metadata object.
  60. foreach (var depName in allDependenciesInFile)
  61. {
  62. if (typeToGuidMap.TryGetValue(depName, out var depGuid) && !string.IsNullOrEmpty(depGuid) && !metadata.DependencyGuids.Contains(depGuid))
  63. {
  64. metadata.DependencyGuids.Add(depGuid);
  65. }
  66. }
  67. }
  68. }
  69. }