Example #1
0
        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);
        }
Example #2
0
        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());
        }
Example #3
0
        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);
        }
Example #4
0
        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;
        }
Example #5
0
        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);
        }
Example #6
0
        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());
        }
Example #7
0
        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);
        }
Example #8
0
        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);
        }
Example #9
0
        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();
            }
        }
Example #10
0
        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);
        }
Example #12
0
        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);
        }