123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- using System.IO;
- using System.Linq;
- using UnityEditor;
- using UnityEngine;
- using UnityEditor.Compilation;
- using System.Collections.Generic;
- using IntelligentProjectAnalyzer.Analyzer;
- using UnityEditor.SceneManagement;
- // All using statements now refer to the new data-only class
- using static IntelligentProjectAnalyzer.Editor.DependencyBuilderData;
- namespace IntelligentProjectAnalyzer.Editor
- {
- /// <summary>
- /// Handles all communication with the Unity API that must occur on the main thread
- /// to gather data for the dependency analysis.
- /// </summary>
- public static class AssetDataFetcher
- {
- /// <summary>
- /// Finds all relevant asset GUIDs for scripts, prefabs, and ScriptableObjects.
- /// </summary>
- /// <returns>A tuple containing queues of GUIDs for each asset type.</returns>
- public static (Queue<string> scriptGuids, Queue<string> prefabGuids, Queue<string> soGuids, Queue<string> sceneGuids, Queue<string> miscGuids) FindAssetGuids()
- {
- var scripts = new Queue<string>(AssetDatabase.FindAssets("t:MonoScript"));
- var prefabs = new Queue<string>(AssetDatabase.FindAssets("t:Prefab"));
- var scriptableObjects = new Queue<string>(AssetDatabase.FindAssets("t:ScriptableObject"));
- var scenes = new Queue<string>(AssetDatabase.FindAssets("t:Scene"));
- var allGuids = new Queue<string>(AssetDatabase.FindAssets(""));
-
- var knownGuids = new HashSet<string>();
- knownGuids.UnionWith(scriptableObjects);
- knownGuids.UnionWith(prefabs);
- knownGuids.UnionWith(scripts);
- knownGuids.UnionWith(scenes);
-
- var miscGuids = new Queue<string>(allGuids.Except(knownGuids));
- return (scripts, prefabs, scriptableObjects, scenes, miscGuids);
- }
- /// <summary>
- /// Gathers metadata for a single script asset. Its dependencies will be filled in later.
- /// </summary>
- public static ScriptMetadata PreFetchScriptMetadata(string guid)
- {
- var assetPath = AssetDatabase.GUIDToAssetPath(guid);
- if (string.IsNullOrEmpty(assetPath) || !assetPath.StartsWith("Assets/")) return null;
- return new ScriptMetadata { Guid = guid, FullPath = Path.GetFullPath(assetPath).Replace('\\', '/') };
- }
- /// <summary>
- /// Gathers metadata for a single prefab asset, including its direct script dependencies.
- /// </summary>
- public static PrefabMetadata PreFetchPrefabMetadata(string guid)
- {
- var assetPath = AssetDatabase.GUIDToAssetPath(guid);
- if (string.IsNullOrEmpty(assetPath) || !assetPath.StartsWith("Assets/")) return null;
-
- var go = AssetDatabase.LoadAssetAtPath<GameObject>(assetPath);
- if (go == null) return null;
- var prefabMetadata = new PrefabMetadata { Guid = guid };
-
- var hash = new HashSet<string>();
- // Find all components on the prefab and its children to get their script GUIDs.
- var components = go.GetComponentsInChildren<Component>(true);
- foreach (var component in components)
- {
- if (component == null) continue;
-
- var script = MonoScript.FromMonoBehaviour(component as MonoBehaviour);
- if (script == null) continue;
- var scriptAssetPath = AssetDatabase.GetAssetPath(script);
- if (string.IsNullOrEmpty(scriptAssetPath)) continue;
- var scriptGuid = AssetDatabase.AssetPathToGUID(scriptAssetPath);
- if (!string.IsNullOrEmpty(scriptGuid) && scriptAssetPath.StartsWith("Assets/"))
- {
- hash.Add(scriptGuid);
- }
- }
-
- var assetDependencies = AssetDatabase.GetDependencies(assetPath);
- foreach (var dependency in assetDependencies)
- {
- if (string.IsNullOrEmpty(dependency) || !dependency.StartsWith("Assets/") || dependency == assetPath)
- {
- continue;
- }
- var dependencyGuid = AssetDatabase.AssetPathToGUID(dependency);
- if (!string.IsNullOrEmpty(dependencyGuid))
- {
- hash.Add(dependencyGuid);
- }
- }
-
- prefabMetadata.DependencyGuids = hash.ToList();
- return prefabMetadata;
- }
- /// <summary>
- /// Gathers metadata for a single ScriptableObject asset, including its direct script dependency.
- /// </summary>
- public static ScriptableObjectMetadata PreFetchScriptableObjectMetadata(string guid)
- {
- var assetPath = AssetDatabase.GUIDToAssetPath(guid);
- if (string.IsNullOrEmpty(assetPath) || !assetPath.StartsWith("Assets/")) return null;
- var so = AssetDatabase.LoadAssetAtPath<ScriptableObject>(assetPath);
- if (so == null) return null;
- var script = MonoScript.FromScriptableObject(so);
- if (script == null) return null;
- var scriptAssetPath = AssetDatabase.GetAssetPath(script);
- if (string.IsNullOrEmpty(scriptAssetPath)) return null;
- var hash = new HashSet<string>();
- var scriptGuid = AssetDatabase.AssetPathToGUID(scriptAssetPath);
- var soMetadata = new ScriptableObjectMetadata { Guid = guid };
- if (!string.IsNullOrEmpty(scriptGuid) && scriptAssetPath.StartsWith("Assets/"))
- {
- hash.Add(scriptGuid);
- }
-
- var assetDependencies = AssetDatabase.GetDependencies(assetPath);
- foreach (var dependency in assetDependencies)
- {
- if (string.IsNullOrEmpty(dependency) || !dependency.StartsWith("Assets/") || dependency == assetPath)
- {
- continue;
- }
- var dependencyGuid = AssetDatabase.AssetPathToGUID(dependency);
- if (!string.IsNullOrEmpty(dependencyGuid))
- {
- hash.Add(dependencyGuid);
- }
- }
-
- soMetadata.DependencyGuids = hash.ToList();
- return soMetadata;
- }
- /// <summary>
- /// Gathers all data required to initialize the Roslyn C# analysis.
- /// </summary>
- public static RoslynSetupData PreFetchRoslynSetupData(List<ScriptMetadata> scriptMetadata)
- {
- var setupData = new RoslynSetupData
- {
- SourceFiles = scriptMetadata.Select(s => s.FullPath).ToArray(),
- PreprocessorSymbols = EditorUserBuildSettings.activeScriptCompilationDefines
- };
- var references = new List<string>();
- foreach (var assembly in CompilationPipeline.GetAssemblies())
- {
- references.AddRange(assembly.compiledAssemblyReferences.Select(Path.GetFullPath));
- }
- setupData.References = references.Distinct().ToArray();
- var prefixes = new List<string> { "System", "UnityEngine", "UnityEditor" };
- var settings = AnalyzerSettingsCrud.GetOrCreateSettings();
- if (settings != null && settings.CustomSystemTypes != null)
- {
- prefixes.AddRange(settings.CustomSystemTypes.Where(p => !string.IsNullOrEmpty(p) && !prefixes.Contains(p)));
- }
- setupData.SystemTypePrefixes = prefixes;
- setupData.TypeToGuidMap = new Dictionary<string, string>();
- var tempAnalyzer = new RoslynTypeDependencyAnalyzer(setupData.SourceFiles, setupData.References, setupData.PreprocessorSymbols, setupData.SystemTypePrefixes);
- foreach (var pair in tempAnalyzer.TypeToPathMap)
- {
- var projectPath = Directory.GetParent(Application.dataPath)?.FullName.Replace('\\', '/');
- var relativePath = pair.Value.Replace('\\', '/').Replace(projectPath + "/", "");
- var guid = AssetDatabase.AssetPathToGUID(relativePath);
- if (!string.IsNullOrEmpty(guid)) { setupData.TypeToGuidMap[pair.Key] = guid; }
- }
- return setupData;
- }
- public static MiscAssetMetadata PreFetchMiscAssetMetadata(string guid)
- {
- var assetPath = AssetDatabase.GUIDToAssetPath(guid);
- if (string.IsNullOrEmpty(assetPath) || !assetPath.StartsWith("Assets/")) return null;
-
- var miscMetaData = new MiscAssetMetadata() { Guid = guid };
- var hash = new HashSet<string>();
- var assetDependencies = AssetDatabase.GetDependencies(assetPath);
- foreach (var dependency in assetDependencies)
- {
- if (string.IsNullOrEmpty(dependency) || !dependency.StartsWith("Assets/") || dependency == assetPath)
- {
- continue;
- }
- var dependencyGuid = AssetDatabase.AssetPathToGUID(dependency);
- if (!string.IsNullOrEmpty(dependencyGuid))
- {
- hash.Add(dependencyGuid);
- }
- }
- miscMetaData.DependencyGuids = hash.ToList();
- return miscMetaData;
- }
- public static SceneMetadata PreFetchSceneMetadata(string guid)
- {
- var assetPath = AssetDatabase.GUIDToAssetPath(guid);
- if (string.IsNullOrEmpty(assetPath) || !assetPath.StartsWith("Assets/")) return null;
-
- var scene = EditorSceneManager.OpenScene(assetPath, OpenSceneMode.Single);
- var sceneMetaData = new SceneMetadata() { Guid = guid };
- var hash = new HashSet<string>();
- // Find all components on the scene and its children to get their script GUIDs.
- foreach (var root in scene.GetRootGameObjects())
- {
- var components = root.GetComponentsInChildren<Component>(true);
- foreach (var component in components)
- {
- if (component == null) continue;
-
- var script = MonoScript.FromMonoBehaviour(component as MonoBehaviour);
- if (script == null) continue;
- var scriptAssetPath = AssetDatabase.GetAssetPath(script);
- if (string.IsNullOrEmpty(scriptAssetPath)) continue;
- var scriptGuid = AssetDatabase.AssetPathToGUID(scriptAssetPath);
- if (!string.IsNullOrEmpty(scriptGuid) && scriptAssetPath.StartsWith("Assets/"))
- {
- hash.Add(scriptGuid);
- }
- }
- }
-
- var assetDependencies = AssetDatabase.GetDependencies(assetPath);
- foreach (var dependency in assetDependencies)
- {
- if (string.IsNullOrEmpty(dependency) || !dependency.StartsWith("Assets/") || dependency == assetPath)
- {
- continue;
- }
- var dependencyGuid = AssetDatabase.AssetPathToGUID(dependency);
- if (!string.IsNullOrEmpty(dependencyGuid))
- {
- hash.Add(dependencyGuid);
- }
- }
- sceneMetaData.DependencyGuids = hash.ToList();
- return sceneMetaData;
- }
- }
- }
|