Bug 1614846 - Remove nsIArray use in nsIMsgAccountManager.allFolders. r=mkmelin
authorBen Campbell <benc@thunderbird.net>
Fri, 03 Apr 2020 13:39:10 +0300
changeset 38677 4fd2ffb624922351c4c7ec6a775c78b436339fb3
parent 38676 0e46814e8707ce3acfab8b1849c533e0ae79dc21
child 38678 7e35670fce68f481c32ba9a207cbea3dd0a09093
push id400
push userclokep@gmail.com
push dateMon, 04 May 2020 18:56:09 +0000
reviewersmkmelin
bugs1614846
Bug 1614846 - Remove nsIArray use in nsIMsgAccountManager.allFolders. r=mkmelin
mail/base/modules/MailUtils.jsm
mail/components/extensions/test/xpcshell/test_ext_experiments.js
mail/test/browser/folder-display/browser_recentMenu.js
mailnews/base/content/folder-menupopup.js
mailnews/base/public/nsIMsgAccountManager.idl
mailnews/base/src/nsMsgAccountManager.cpp
mailnews/base/test/unit/test_accountMgr2.js
mailnews/db/gloda/modules/IndexMsg.jsm
--- a/mail/base/modules/MailUtils.jsm
+++ b/mail/base/modules/MailUtils.jsm
@@ -51,19 +51,17 @@ var MailUtils = {
    * the search result corresponding to a mozeml/wdseml file, we need to figure
    * out the folder using the file's path.
    *
    * @param aFile the nsIFile to convert to a folder
    * @returns the nsIMsgFolder corresponding to aFile, or null if the folder
    *          isn't found
    */
   getFolderForFileInProfile(aFile) {
-    let folders = MailServices.accounts.allFolders;
-
-    for (let folder of fixIterator(folders, Ci.nsIMsgFolder)) {
+    for (let folder of MailServices.accounts.allFolders) {
       if (folder.filePath.equals(aFile)) {
         return folder;
       }
     }
     return null;
   },
 
   /**
--- a/mail/components/extensions/test/xpcshell/test_ext_experiments.js
+++ b/mail/components/extensions/test/xpcshell/test_ext_experiments.js
@@ -152,38 +152,38 @@ add_task(async function test_managers() 
                 async testCanGetFolder({ accountId, path }) {
                   let realFolder = context.extension.folderManager.get(
                     accountId,
                     path
                   );
                   return realFolder.getTotalMessages(false);
                 },
                 async testCanConvertFolder() {
-                  let realFolder = [
-                    ...MailServices.accounts.allFolders.enumerate(),
-                  ].find(f => f.name == "test1");
+                  let realFolder = MailServices.accounts.allFolders.find(
+                    f => f.name == "test1"
+                  );
                   return context.extension.folderManager.convert(realFolder);
                 },
                 async testCanGetMessage(messageId) {
                   let realMessage = context.extension.messageManager.get(
                     messageId
                   );
                   return realMessage.subject;
                 },
                 async testCanConvertMessage() {
-                  let realFolder = [
-                    ...MailServices.accounts.allFolders.enumerate(),
-                  ].find(f => f.name == "test1");
+                  let realFolder = MailServices.accounts.allFolders.find(
+                    f => f.name == "test1"
+                  );
                   let realMessage = realFolder.messages.getNext();
                   return context.extension.messageManager.convert(realMessage);
                 },
                 async testCanStartMessageList() {
-                  let realFolder = [
-                    ...MailServices.accounts.allFolders.enumerate(),
-                  ].find(f => f.name == "test1");
+                  let realFolder = MailServices.accounts.allFolders.find(
+                    f => f.name == "test1"
+                  );
                   return context.extension.messageManager.startMessageList(
                     realFolder.messages
                   );
                 },
                 async testCanFindAddressBookItems(
                   bookUID,
                   contactUID,
                   listUID
--- a/mail/test/browser/folder-display/browser_recentMenu.js
+++ b/mail/test/browser/folder-display/browser_recentMenu.js
@@ -23,28 +23,24 @@ var {
 } = ChromeUtils.import(
   "resource://testing-common/mozmill/FolderDisplayHelpers.jsm"
 );
 
 var { MailUtils } = ChromeUtils.import("resource:///modules/MailUtils.jsm");
 var { MailServices } = ChromeUtils.import(
   "resource:///modules/MailServices.jsm"
 );
-var { fixIterator } = ChromeUtils.import(
-  "resource:///modules/iteratorUtils.jsm"
-);
 
 var folder1, folder2;
 var gInitRecentMenuCount;
 
 add_task(function setupModule(module) {
   // Ensure that there are no updated folders to ensure the recent folder
   // is empty.
-  let allFolders = MailServices.accounts.allFolders;
-  for (let folder of fixIterator(allFolders, Ci.nsIMsgFolder)) {
+  for (let folder of MailServices.accounts.allFolders) {
     folder.setStringProperty("MRMTime", "0");
   }
 
   // Try to make these folders first in alphabetic order
   folder1 = create_folder("aaafolder1");
   folder2 = create_folder("aaafolder2");
 
   make_new_sets_in_folder(folder1, [{ count: 3 }]);
--- a/mailnews/base/content/folder-menupopup.js
+++ b/mailnews/base/content/folder-menupopup.js
@@ -558,19 +558,17 @@
        */
       _populateSpecialSubmenu(menu, submenu) {
         let specialType = menu.getAttribute("special");
         if (this._initializedSpecials.has(specialType)) {
           return;
         }
 
         // Iterate through all folders in all accounts matching the current filter.
-        let specialFolders = toArray(
-          fixIterator(MailServices.accounts.allFolders, Ci.nsIMsgFolder)
-        );
+        let specialFolders = MailServices.accounts.allFolders;
         if (this._listener._filterFunction) {
           specialFolders = specialFolders.filter(
             this._listener._filterFunction
           );
         }
 
         switch (specialType) {
           case "recent":
--- a/mailnews/base/public/nsIMsgAccountManager.idl
+++ b/mailnews/base/public/nsIMsgAccountManager.idl
@@ -216,17 +216,17 @@ interface nsIMsgAccountManager : nsISupp
   void notifyServerChanged(in nsIMsgIncomingServer server);
 
   // force account info out to prefs file
   void saveAccountInfo();
 
   ACString getChromePackageName(in ACString aExtensionName);
 
   /// Enumerate all incoming servers and their folders and return in an array.
-  readonly attribute nsIArray allFolders;
+  readonly attribute Array<nsIMsgFolder> allFolders;
 
   /**
    * Iterates over all folders looking for one with the passed in path,
    * and returns the uri for the matching folder. In the future,
    * the folder lookup service will provide this functionality.
    *
    * @param aLocalPath path of the folder whose uri we want.
    * @return the URI of the folder that corresponds to aLocalPath
--- a/mailnews/base/src/nsMsgAccountManager.cpp
+++ b/mailnews/base/src/nsMsgAccountManager.cpp
@@ -2919,36 +2919,41 @@ nsresult nsMsgAccountManager::RemoveVFLi
       msgDBService->UnregisterPendingListener(listener);
       m_virtualFolderListeners.RemoveElement(listener);
       break;
     }
   }
   return NS_OK;
 }
 
-NS_IMETHODIMP nsMsgAccountManager::GetAllFolders(nsIArray **aAllFolders) {
-  NS_ENSURE_ARG_POINTER(aAllFolders);
-
+NS_IMETHODIMP nsMsgAccountManager::GetAllFolders(
+    nsTArray<RefPtr<nsIMsgFolder>> &aAllFolders) {
+  aAllFolders.Clear();
   nsTArray<RefPtr<nsIMsgIncomingServer>> allServers;
   nsresult rv = GetAllServers(allServers);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIMutableArray> allFolders(
       do_CreateInstance(NS_ARRAY_CONTRACTID, &rv));
   NS_ENSURE_SUCCESS(rv, rv);
 
   for (auto server : allServers) {
     if (server) {
       nsCOMPtr<nsIMsgFolder> rootFolder;
       server->GetRootFolder(getter_AddRefs(rootFolder));
       if (rootFolder) rootFolder->ListDescendants(allFolders);
     }
   }
 
-  allFolders.forget(aAllFolders);
+  uint32_t length;
+  allFolders->GetLength(&length);
+  for (uint32_t i = 0; i < length; ++i) {
+    nsCOMPtr<nsIMsgFolder> folder = do_QueryElementAt(allFolders, i);
+    aAllFolders.AppendElement(folder);
+  }
   return NS_OK;
 }
 
 NS_IMETHODIMP nsMsgAccountManager::OnItemAdded(nsIMsgFolder *parentItem,
                                                nsISupports *item) {
   nsCOMPtr<nsIMsgFolder> folder = do_QueryInterface(item);
   // just kick out with a success code if the item in question is not a folder
   if (!folder) return NS_OK;
@@ -3269,28 +3274,21 @@ nsMsgAccountManager::FolderUriForPath(ns
                                       nsACString &aMailboxUri) {
   NS_ENSURE_ARG_POINTER(aLocalPath);
   bool equals;
   if (m_lastPathLookedUp &&
       NS_SUCCEEDED(aLocalPath->Equals(m_lastPathLookedUp, &equals)) && equals) {
     aMailboxUri = m_lastFolderURIForPath;
     return NS_OK;
   }
-  nsCOMPtr<nsIArray> folderArray;
-  nsresult rv = GetAllFolders(getter_AddRefs(folderArray));
+  nsTArray<RefPtr<nsIMsgFolder>> folders;
+  nsresult rv = GetAllFolders(folders);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  uint32_t count;
-  rv = folderArray->GetLength(&count);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  for (uint32_t i = 0; i < count; i++) {
-    nsCOMPtr<nsIMsgFolder> folder(do_QueryElementAt(folderArray, i, &rv));
-    NS_ENSURE_SUCCESS(rv, rv);
-
+  for (auto folder : folders) {
     nsCOMPtr<nsIFile> folderPath;
     rv = folder->GetFilePath(getter_AddRefs(folderPath));
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Check if we're equal
     rv = folderPath->Equals(aLocalPath, &equals);
     NS_ENSURE_SUCCESS(rv, rv);
 
--- a/mailnews/base/test/unit/test_accountMgr2.js
+++ b/mailnews/base/test/unit/test_accountMgr2.js
@@ -51,14 +51,19 @@ add_task(async function() {
   // The identities we explicitly created.
   Assert.equal(mgr.allIdentities.length, 3);
 
   // Check we find the right number of identities associated with each server.
   Assert.equal(mgr.getIdentitiesForServer(acc1.incomingServer).length, 2);
   Assert.equal(mgr.getIdentitiesForServer(acc2.incomingServer).length, 2);
   Assert.equal(mgr.getIdentitiesForServer(mgr.localFoldersServer).length, 0);
 
-  // id1 and id2 are on separate accounts (and servers)
+  // id1 and id2 are on separate accounts (and servers).
   Assert.equal(mgr.getServersForIdentity(id1).length, 1);
   Assert.equal(mgr.getServersForIdentity(id2).length, 1);
-  // id3 is shared
+  // id3 is shared.
   Assert.equal(mgr.getServersForIdentity(id3).length, 2);
+
+  // Does allFolders return the default folders we'd expect?
+  // IMAP has Inbox only.
+  // POP3 and local accounts both have Inbox and Trash.
+  Assert.equal(mgr.allFolders.length, 1 + 2 + 2);
 });
--- a/mailnews/db/gloda/modules/IndexMsg.jsm
+++ b/mailnews/db/gloda/modules/IndexMsg.jsm
@@ -1043,18 +1043,17 @@ var GlodaMsgIndexer = {
    */
   *_worker_indexingSweep(aJob) {
     if (!aJob.mappedFolders) {
       // Walk the folders and make sure all the folders we would want to index
       //  are mapped.  Build up a list of GlodaFolders as we go, so that we can
       //  sort them by their indexing priority.
       let foldersToProcess = (aJob.foldersToProcess = []);
 
-      let allFolders = MailServices.accounts.allFolders;
-      for (let folder of fixIterator(allFolders, Ci.nsIMsgFolder)) {
+      for (let folder of MailServices.accounts.allFolders) {
         if (this.shouldIndexFolder(folder)) {
           foldersToProcess.push(Gloda.getFolderForFolder(folder));
         }
       }
 
       // sort the folders by priority (descending)
       foldersToProcess.sort(function(a, b) {
         return b.indexingPriority - a.indexingPriority;