private static bool AssetIsFilteredOut(AssetInfo referencedAsset, int depth) { if (MaintainerPersonalSettings.References.showAssetsWithoutReferences || depth != 0) { return(false); } if (referencedAsset.referencedAtInfoList.Length == 0) { return(true); } var allIgnored = true; foreach (var referencedAtInfo in referencedAsset.referencedAtInfoList) { if (CSFilterTools.IsValueMatchesAnyFilter(referencedAtInfo.assetInfo.Path, MaintainerSettings.References.pathIgnoresFilters)) { continue; } if (referencedAtInfo.assetInfo.Kind == AssetKind.FromPackage) { continue; } allIgnored = false; break; } return(allIgnored); }
private static void MigrateAllIgnores(ICollection <string> oldFilters, ref FilterItem[] newFilters, FilterKind filterKind) { if (oldFilters == null || oldFilters.Count == 0) { return; } var newFiltersList = new List <FilterItem>(oldFilters.Count); foreach (var oldFilter in oldFilters) { if (CSFilterTools.IsValueMatchesAnyFilter(oldFilter, newFilters)) { continue; } newFiltersList.Add(FilterItem.Create(oldFilter, filterKind)); } ArrayUtility.AddRange(ref newFilters, newFiltersList.ToArray()); }
private static bool MigrateAllIgnores(string[] oldFilters, ref FilterItem[] newFilters, FilterKind filterKind) { if (oldFilters == null || oldFilters.Length == 0) { return(false); } var newFiltersList = new List <FilterItem>(oldFilters.Length); foreach (var oldFilter in oldFilters) { if (CSFilterTools.IsValueMatchesAnyFilter(oldFilter, newFilters)) { continue; } newFiltersList.Add(FilterItem.Create(oldFilter, filterKind)); } ArrayUtility.AddRange(ref newFilters, newFiltersList.ToArray()); return(true); }
private static void ExcludeSubFoldersOfEmptyFolders(ref List <string> emptyFolders) { var emptyFoldersFiltered = new List <string>(emptyFolders.Count); for (var i = emptyFolders.Count - 1; i >= 0; i--) { var folder = emptyFolders[i]; if (CSFilterTools.HasEnabledFilters(ProjectSettings.Cleaner.pathIncludesFilters)) { var emptyFolder = CSPathTools.GetProjectRelativePath(folder); if (!CSFilterTools.IsValueMatchesAnyFilter(emptyFolder, ProjectSettings.Cleaner.pathIncludesFilters)) { continue; } } if (!CSArrayTools.IsItemContainsAnyStringFromArray(folder, emptyFoldersFiltered)) { emptyFoldersFiltered.Add(folder); } } emptyFolders = emptyFoldersFiltered; }
private static bool LookForReferences(FilterItem[] selectedAssets, List <ReferencesTreeElement> results) { var canceled = !CSSceneTools.SaveCurrentModifiedScenes(false); if (!canceled) { var map = AssetsMap.GetUpdated(); if (map == null) { return(true); } var count = map.assets.Count; var updateStep = Math.Max(count / MaintainerSettings.UpdateProgressStep, 1); var root = new ReferencesTreeElement { id = results.Count, name = "root", depth = -1 }; results.Add(root); for (var i = 0; i < count; i++) { if (i % updateStep == 0 && EditorUtility.DisplayCancelableProgressBar( string.Format(ProgressCaption, 1, PhasesCount), string.Format(ProgressText, "Building references tree", i + 1, count), (float)i / count)) { canceled = true; break; } var assetInfo = map.assets[i]; // excludes settings assets from the list depth 0 items if (assetInfo.Kind == AssetKind.Settings) { continue; } // excludes all assets except selected ones from the list depth 0 items, if any was selected if (selectedAssets != null) { if (!CSFilterTools.IsValueMatchesAnyFilter(assetInfo.Path, selectedAssets)) { continue; } } if (MaintainerSettings.References.pathIncludesFilters != null && MaintainerSettings.References.pathIncludesFilters.Length > 0) { // excludes all root assets except included ones if (!CSFilterTools.IsValueMatchesAnyFilter(assetInfo.Path, MaintainerSettings.References.pathIncludesFilters)) { continue; } } // excludes ignored root asset if (CSFilterTools.IsValueMatchesAnyFilter(assetInfo.Path, MaintainerSettings.References.pathIgnoresFilters)) { continue; } var branchElements = new List <ReferencesTreeElement>(); TreeBuilder.BuildTreeBranch(assetInfo, 0, results.Count, branchElements); results.AddRange(branchElements); } } if (!canceled) { canceled = ReferenceEntryFinder.FillReferenceEntries(); } if (!canceled) { AssetsMap.Save(); } if (canceled) { ReferencesTab.AutoShowExistsNotification = false; ReferencesTab.AutoSelectPath = null; } return(canceled); }
internal static ReferencesTreeElement[] GetReferences(FilterItem[] allTargetAssets, FilterItem[] newTargetAssets, bool showResults = true) { var results = new List <ReferencesTreeElement>(); ConjunctionInfoList.Clear(); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport); try { var sw = Stopwatch.StartNew(); CSEditorTools.lastRevealSceneOpenResult = null; var searchCanceled = LookForReferences(allTargetAssets, results); sw.Stop(); EditorUtility.ClearProgressBar(); if (!searchCanceled) { var resultsCount = results.Count; if (resultsCount <= 1) { ReferencesTab.AutoSelectPath = null; MaintainerWindow.ShowNotification("Nothing found!"); } else if (newTargetAssets != null && newTargetAssets.Length > 0) { var found = false; foreach (var result in results) { if (result.depth == 0 && CSFilterTools.IsValueMatchesAnyFilter(result.assetPath, newTargetAssets)) { found = true; break; } } if (!found) { ReferencesTab.AutoSelectPath = null; MaintainerWindow.ShowNotification("Nothing found!"); } } Debug.Log(Maintainer.LogPrefix + ModuleName + " results: " + (resultsCount - 1) + " items found in " + sw.Elapsed.TotalSeconds.ToString("0.000", CultureInfo.InvariantCulture) + " seconds."); } else { Debug.Log(Maintainer.LogPrefix + ModuleName + "Search canceled by user!"); } } catch (Exception e) { Debug.LogError(Maintainer.LogPrefix + ModuleName + ": " + e); EditorUtility.ClearProgressBar(); } BuildSelectedAssetsFromResults(results); SearchResultsStorage.ReferencesSearchResults = results.ToArray(); if (showResults) { MaintainerWindow.ShowReferences(); } return(results.ToArray()); }
private static bool FindEmptyFoldersRecursive(List <string> foundEmptyFolders, string root, bool showProgress, out bool canceledByUser) { var rootSubFolders = Directory.GetDirectories(root); var canceled = false; var emptySubFolders = true; var count = rootSubFolders.Length; var updateStep = Math.Max(count / MaintainerSettings.UpdateProgressStep, 1); for (var i = 0; i < count; i++) { var folder = CSPathTools.EnforceSlashes(rootSubFolders[i]); folderIndex++; if (showProgress && (i % updateStep == 0) && EditorUtility.DisplayCancelableProgressBar( string.Format(ProgressCaption, currentPhase, phasesCount, folderIndex, foldersCount), "Scanning folders...", (float)folderIndex / foldersCount)) { canceled = true; break; } if (CSFilterTools.IsValueMatchesAnyFilter(folder.Replace('\\', '/'), MaintainerSettings.Cleaner.pathIgnoresFilters)) { emptySubFolders = false; continue; } emptySubFolders &= FindEmptyFoldersRecursive(foundEmptyFolders, folder, showProgress, out canceled); if (canceled) { break; } } if (canceled) { canceledByUser = true; return(false); } var rootFolderHasFiles = true; var filesInRootFolder = Directory.GetFiles(root); foreach (var file in filesInRootFolder) { if (file.EndsWith(".meta", StringComparison.OrdinalIgnoreCase)) { continue; } rootFolderHasFiles = false; break; } var rootFolderEmpty = emptySubFolders && rootFolderHasFiles; if (rootFolderEmpty) { foundEmptyFolders.Add(root); } canceledByUser = false; return(rootFolderEmpty); }
private static bool AssetInIgnores(AssetInfo assetInfo, List <string> ignoredScenes) { if (assetInfo.Type == CSReflectionTools.monoScriptType /* && !MaintainerSettings.Cleaner.findUnreferencedScripts*/) { return(true); } if (assetInfo.Type == CSReflectionTools.textAssetType) { return(true); } if (assetInfo.Type == CSReflectionTools.spriteAtlasType) { var atlas = AssetDatabase.LoadAssetAtPath <UnityEngine.U2D.SpriteAtlas>(assetInfo.Path); if (atlas != null) { var so = new SerializedObject(atlas); // source: SpriteAtlasInspector var bindAsDefaultProperty = so.FindProperty("m_EditorData.bindAsDefault"); if (bindAsDefaultProperty != null) { if (bindAsDefaultProperty.boolValue) { return(true); } } else { Debug.LogError(Maintainer.LogPrefix + "Can't parse UnityEngine.U2D.SpriteAtlas, please report to " + Maintainer.SupportEmail); } } else { Debug.LogWarning(Maintainer.LogPrefix + "Couldn't load SpriteAtlas: " + assetInfo.Path); } } if (assetInfo.Type == CSReflectionTools.assemblyDefinitionAssetType) { return(true); } if (assetInfo.Type == CSReflectionTools.defaultAssetType) { var importer = AssetImporter.GetAtPath(assetInfo.Path); if (importer is PluginImporter) { return(true); } if (importer.ToString() == " (UnityEngine.DefaultImporter)") { return(true); } } if (CSFilterTools.IsValueMatchesAnyFilter(assetInfo.Path, MaintainerSettings.Cleaner.MandatoryFilters)) { return(true); } if (CSFilterTools.IsValueMatchesAnyFilter(assetInfo.Path, MaintainerSettings.Cleaner.pathIgnoresFilters)) { return(true); } if (assetInfo.Type == CSReflectionTools.sceneAssetType && ignoredScenes.IndexOf(assetInfo.Path) != -1) { return(true); } foreach (var referencedAtInfo in assetInfo.referencedAtInfoList) { if (referencedAtInfo.assetInfo.SettingsKind != AssetSettingsKind.NotSettings && referencedAtInfo.assetInfo.SettingsKind != AssetSettingsKind.EditorBuildSettings) { return(true); } if (referencedAtInfo.assetInfo.Kind == AssetKind.FromPackage) { return(true); } } var assetBundleName = AssetDatabase.GetImplicitAssetBundleName(assetInfo.Path); if (!string.IsNullOrEmpty(assetBundleName)) { return(true); } return(false); }
private void DrawMoreButton(AssetRecord assetRecord) { if (UIHelpers.RecordButton(assetRecord, "Shows menu with additional actions for this record.", CSIcons.More)) { var menu = new GenericMenu(); if (!string.IsNullOrEmpty(assetRecord.path)) { menu.AddItem(new GUIContent("Ignore/Full Path"), false, () => { if (!CSFilterTools.IsValueMatchesAnyFilter(assetRecord.assetDatabasePath, MaintainerSettings.Cleaner.pathIgnoresFilters)) { var newFilter = FilterItem.Create(assetRecord.assetDatabasePath, FilterKind.Path); ArrayUtility.Add(ref MaintainerSettings.Cleaner.pathIgnoresFilters, newFilter); MaintainerWindow.ShowNotification("Ignore added: " + assetRecord.assetDatabasePath); CleanerFiltersWindow.Refresh(); if (MaintainerSettings.Cleaner.rescanAfterContextIgnore) { StartSearch(); } } else { MaintainerWindow.ShowNotification("Already added to the ignores!"); } }); var dir = Directory.GetParent(assetRecord.assetDatabasePath); if (!CSPathTools.IsAssetsRootPath(dir.FullName)) { menu.AddItem(new GUIContent("Ignore/Parent Folder"), false, () => { var dirPath = CSPathTools.EnforceSlashes(dir.ToString()); if (!CSFilterTools.IsValueMatchesAnyFilter(dirPath, MaintainerSettings.Cleaner.pathIgnoresFilters)) { var newFilter = FilterItem.Create(dirPath, FilterKind.Directory); ArrayUtility.Add(ref MaintainerSettings.Cleaner.pathIgnoresFilters, newFilter); MaintainerWindow.ShowNotification("Ignore added: " + dirPath); CleanerFiltersWindow.Refresh(); if (MaintainerSettings.Cleaner.rescanAfterContextIgnore) { StartSearch(); } } else { MaintainerWindow.ShowNotification("Already added to the ignores!"); } }); } var extension = Path.GetExtension(assetRecord.path); if (!string.IsNullOrEmpty(extension)) { menu.AddItem(new GUIContent("Ignore/\"" + extension + "\" Extension"), false, () => { if (!CSFilterTools.IsValueMatchesAnyFilterOfKind(extension, MaintainerSettings.Cleaner.pathIgnoresFilters, FilterKind.Extension)) { var newFilter = FilterItem.Create(extension, FilterKind.Extension, true); ArrayUtility.Add(ref MaintainerSettings.Cleaner.pathIgnoresFilters, newFilter); MaintainerWindow.ShowNotification("Ignore added: " + extension); CleanerFiltersWindow.Refresh(); if (MaintainerSettings.Cleaner.rescanAfterContextIgnore) { StartSearch(); } } else { MaintainerWindow.ShowNotification("Already added to the ignores!"); } }); } } menu.ShowAsContext(); } }
private void DrawMoreButton(AssetIssueRecord record) { if (!UIHelpers.RecordButton(record, "Shows menu with additional actions for this record.", CSIcons.More)) { return; } var menu = new GenericMenu(); if (!string.IsNullOrEmpty(record.Path)) { menu.AddItem(new GUIContent("Ignore/Full Path"), false, () => { if (!CSFilterTools.IsValueMatchesAnyFilter(record.Path, ProjectSettings.Issues.pathIgnoresFilters)) { var newFilter = FilterItem.Create(record.Path, FilterKind.Path); ArrayUtility.Add(ref ProjectSettings.Issues.pathIgnoresFilters, newFilter); ApplyNewIgnoreFilter(newFilter); MaintainerWindow.ShowNotification("Ignore added: " + record.Path); CleanerFiltersWindow.Refresh(); } else { MaintainerWindow.ShowNotification("Already added to the ignores!"); } }); var dir = Directory.GetParent(record.Path); if (!CSPathTools.IsAssetsRootPath(dir.FullName)) { menu.AddItem(new GUIContent("Ignore/Parent Folder"), false, () => { var dirPath = CSPathTools.EnforceSlashes(dir.ToString()); if (!CSFilterTools.IsValueMatchesAnyFilter(dirPath, ProjectSettings.Issues.pathIgnoresFilters)) { var newFilter = FilterItem.Create(dirPath, FilterKind.Directory); ArrayUtility.Add(ref ProjectSettings.Issues.pathIgnoresFilters, newFilter); ApplyNewIgnoreFilter(newFilter); MaintainerWindow.ShowNotification("Ignore added: " + dirPath); CleanerFiltersWindow.Refresh(); } else { MaintainerWindow.ShowNotification("Already added to the ignores!"); } }); } } var objectIssue = record as GameObjectIssueRecord; if (objectIssue != null) { if (!string.IsNullOrEmpty(objectIssue.componentName)) { menu.AddItem(new GUIContent("Ignore/\"" + objectIssue.componentName + "\" Component"), false, () => { if (!CSFilterTools.IsValueMatchesAnyFilter(objectIssue.componentName, ProjectSettings.Issues.componentIgnoresFilters)) { var newFilter = FilterItem.Create(objectIssue.componentName, FilterKind.Type); ArrayUtility.Add(ref ProjectSettings.Issues.componentIgnoresFilters, newFilter); ApplyNewIgnoreFilter(newFilter); MaintainerWindow.ShowNotification("Ignore added: " + objectIssue.componentName); CleanerFiltersWindow.Refresh(); } else { MaintainerWindow.ShowNotification("Already added to the ignores!"); } }); } } menu.ShowAsContext(); }
private static bool LookForAssetsReferences(FilterItem[] selectedAssets, List <ProjectReferenceItem> results) { var canceled = !CSSceneTools.SaveCurrentModifiedScenes(false); if (!canceled) { var map = AssetsMap.GetUpdated(); if (map == null) { return(true); } var count = map.assets.Count; #if !UNITY_2020_1_OR_NEWER var updateStep = Math.Max(count / ProjectSettings.UpdateProgressStep, 1); #endif var root = new ProjectReferenceItem { id = results.Count, name = "root", depth = -1 }; results.Add(root); for (var i = 0; i < count; i++) { if ( #if !UNITY_2020_1_OR_NEWER i % updateStep == 0 && #endif EditorUtility.DisplayCancelableProgressBar( string.Format(ReferencesFinder.ProgressCaption, 1, ReferencesFinder.PhasesCount), string.Format(ReferencesFinder.ProgressText, "Building references tree", i + 1, count), (float)i / count)) { canceled = true; break; } var assetInfo = map.assets[i]; // excludes settings assets from the list depth 0 items if (assetInfo.Kind == AssetKind.Settings) { continue; } // excludes all assets except selected ones from the list depth 0 items, if any was selected if (selectedAssets != null) { if (!CSFilterTools.IsValueMatchesAnyFilter(assetInfo.Path, selectedAssets)) { continue; } } if (ProjectSettings.References.pathIncludesFilters != null && ProjectSettings.References.pathIncludesFilters.Length > 0) { // excludes all root assets except included ones if (!CSFilterTools.IsValueMatchesAnyFilter(assetInfo.Path, ProjectSettings.References.pathIncludesFilters)) { continue; } } // excludes ignored root asset if (CSFilterTools.IsValueMatchesAnyFilter(assetInfo.Path, ProjectSettings.References.pathIgnoresFilters)) { continue; } var branchElements = new List <ProjectReferenceItem>(); ProjectScopeReferencesTreeBuilder.BuildTreeBranch(assetInfo, 0, results.Count, ConjunctionInfoList, branchElements); results.AddRange(branchElements); } } if (!canceled) { canceled = ProjectEntryFinder.FillProjectScopeReferenceEntries(ConjunctionInfoList, TryAddEntryToMatchedConjunctions); } // TODO: remove this work-around when this bug will be fixed: // https://issuetracker.unity3d.com/issues/assets-used-in-components-of-a-nested-prefab-are-counted-as-direct-dependencies-of-all-higher-level-nested-prefabs for (var i = results.Count - 1; i >= 0; i--) { var result = results[i]; var resultEntries = result.referencingEntries; if (resultEntries == null || resultEntries.Length == 0) { continue; } foreach (var referencingEntry in resultEntries) { if (referencingEntry.Location == Location.NotFound && result.assetTypeName == "GameObject") { results.Remove(result); break; } } } if (!canceled) { AssetsMap.Save(); } if (canceled) { ProjectReferencesTab.AutoSelectPath = null; } return(canceled); }
private static bool ScanProjectFiles(ICollection <CleanerRecord> results, bool showProgress = true) { currentPhase++; var ignoredScenes = new List <string>(); if (ProjectSettings.Cleaner.ignoreScenesInBuild) { ignoredScenes.AddRange(CSSceneTools.GetScenesInBuild(!ProjectSettings.Cleaner.ignoreOnlyEnabledScenesInBuild)); } foreach (var sceneFilter in ProjectSettings.Cleaner.sceneIgnoresFilters) { if (!sceneFilter.enabled) { continue; } if (ignoredScenes.IndexOf(sceneFilter.value) == -1) { ignoredScenes.Add(sceneFilter.value); } } CheckScenesForExistence(results, ignoredScenes); if (ignoredScenes.Count == 0) { if (!UserSettings.Cleaner.muteNoIgnoredScenesWarning) { var dialogResult = EditorUtility.DisplayDialogComplex( "No ignored scenes!", "No scenes were added to the build settings or to the Filters > Scenes Ignores.\n" + "All not ignored scenes are treated as unused if not referenced somewhere in other ignored assets.", "Proceed anyway", "Proceed and never show again", "Cancel"); if (dialogResult == 1) { UserSettings.Cleaner.muteNoIgnoredScenesWarning = true; UserSettings.Save(); } else if (dialogResult == 2) { return(false); } } results.Add(CleanerWarningRecord.Create("No scenes added to the build settings or Filters > Scenes Ignores tab.\n" + "Search may include all assets used in your game scenes!")); } var map = AssetsMap.GetUpdated(); if (map == null) { results.Add(CleanerErrorRecord.Create("Can't get assets map!")); return(false); } EditorUtility.DisplayCancelableProgressBar(string.Format(ProgressCaption, currentPhase, phasesCount, 0, 0), "Analyzing Assets Map for references...", 0); #if UNITY_2019_3_OR_NEWER BuildReportAnalyzer.Init(); #endif var allAssetsInProject = map.assets; var count = allAssetsInProject.Count; #if !UNITY_2020_1_OR_NEWER var updateStep = Math.Max(count / ProjectSettings.UpdateProgressStep, 1); #endif var referencedAssets = new HashSet <AssetInfo>(); for (var i = 0; i < count; i++) { if (showProgress #if !UNITY_2020_1_OR_NEWER && i % updateStep == 0 #endif && i != 0 && EditorUtility.DisplayCancelableProgressBar( string.Format(ProgressCaption, currentPhase, phasesCount, i + 1, count), "Analyzing Assets Map for references...", (float)(i + 1) / count)) { return(true); } var asset = allAssetsInProject[i]; /*if (asset.Path.EndsWith("1.pdf")) * { * Debug.Log(asset.Type); * if (asset.Type == CSReflectionTools.defaultAssetType) * { * var importer = AssetImporter.GetAtPath(asset.Path); * Debug.Log(importer); * } * }*/ if (asset.Kind != AssetKind.Regular) { continue; } if (AssetInIgnores(asset, ignoredScenes)) { referencedAssets.Add(asset); var references = asset.GetReferencesRecursive(); foreach (var reference in references) { referencedAssets.Add(reference); } } #if UNITY_2019_3_OR_NEWER if (BuildReportAnalyzer.IsFileInBuildReport(asset.GUID)) { referencedAssets.Add(asset); var references = asset.GetReferencesRecursive(); foreach (var reference in references) { if (!referencedAssets.Contains(reference)) { referencedAssets.Add(reference); } } } #endif if (AssetInIgnoresSecondPass(asset, referencedAssets)) { referencedAssets.Add(asset); var references = asset.GetReferencesRecursive(); foreach (var reference in references) { if (!referencedAssets.Contains(reference)) { referencedAssets.Add(reference); } } } } var unreferencedAssets = new List <AssetInfo>(count); for (var i = 0; i < count; i++) { if (showProgress #if !UNITY_2020_1_OR_NEWER && i % updateStep == 0 #endif && i != 0 && EditorUtility.DisplayCancelableProgressBar( string.Format(ProgressCaption, currentPhase, phasesCount, i + 1, count), "Filtering out unreferenced assets...", (float)(i + 1) / count)) { return(true); } var asset = allAssetsInProject[i]; if (asset.Kind != AssetKind.Regular) { continue; } if (CSFilterTools.HasEnabledFilters(ProjectSettings.Cleaner.pathIncludesFilters)) { if (!CSFilterTools.IsValueMatchesAnyFilter(asset.Path, ProjectSettings.Cleaner.pathIncludesFilters)) { continue; } } if (!referencedAssets.Contains(asset)) { if (unreferencedAssets.IndexOf(asset) == -1) { unreferencedAssets.Add(asset); } } } count = unreferencedAssets.Count; #if !UNITY_2020_1_OR_NEWER updateStep = Math.Max(count / ProjectSettings.UpdateProgressStep, 1); #endif for (var i = count - 1; i > -1; i--) { if (showProgress #if !UNITY_2020_1_OR_NEWER && i % updateStep == 0 #endif && i != 0) { var index = count - i; if (EditorUtility.DisplayCancelableProgressBar( string.Format(ProgressCaption, currentPhase, phasesCount, index, count), "Populating results...", (float)index / count)) { return(true); } } var unreferencedAsset = unreferencedAssets[i]; results.Add(AssetRecord.Create(RecordType.UnreferencedAsset, unreferencedAsset)); } return(false); }