Bug 1353542 - Add an eslint rule deprecating usage of Task.jsm in browser/ and toolkit/, r=Mossop.
authorFlorian Quèze <florian@queze.net>
Fri, 12 May 2017 14:54:42 +0200
changeset 406191 b2d4e9f99355b57b0433b2f1add8259f00bc7aa5
parent 406190 0929827f535f2c57eef31d3c28fdebb84bc87d95
child 406192 c143205c3f2025e131b8dd4efa64d53fd7e5ac0b
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMossop
bugs1353542
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1353542 - Add an eslint rule deprecating usage of Task.jsm in browser/ and toolkit/, r=Mossop.
browser/.eslintrc.js
browser/base/content/test/general/browser_e10s_chrome_process.js
browser/tools/mozscreenshots/mozscreenshots/extension/configurations/Buttons.jsm
toolkit/.eslintrc.js
toolkit/components/thumbnails/test/browser_thumbnails_storage.js
toolkit/modules/Sqlite.jsm
toolkit/modules/Task.jsm
toolkit/modules/tests/xpcshell/test_Promise.js
tools/lint/eslint/eslint-plugin-mozilla/lib/index.js
tools/lint/eslint/eslint-plugin-mozilla/lib/rules/no-task.js
--- a/browser/.eslintrc.js
+++ b/browser/.eslintrc.js
@@ -20,10 +20,12 @@ module.exports = {
     // Maximum depth callbacks can be nested.
     "max-nested-callbacks": ["error", 8],
 
     // Disallow adding to native types
     "no-extend-native": "error",
 
     "no-mixed-spaces-and-tabs": "error",
     "no-shadow": "error",
+
+    "mozilla/no-task": "error",
   }
 };
--- a/browser/base/content/test/general/browser_e10s_chrome_process.js
+++ b/browser/base/content/test/general/browser_e10s_chrome_process.js
@@ -16,18 +16,17 @@ function makeTest(name, startURL, startP
     info("Loading initial URL");
     browser.loadURI(startURL);
     await waitForDocLoadComplete();
 
     is(browser.currentURI.spec, startURL, "Shouldn't have been redirected");
     is(browser.isRemoteBrowser, startProcessIsRemote, "Should be displayed in the right process");
 
     let docLoadedPromise = waitForDocLoadComplete();
-    let asyncTask = Task.async(transitionTask);
-    let expectSyncChange = await asyncTask(browser, endURL);
+    let expectSyncChange = await transitionTask(browser, endURL);
     if (expectSyncChange) {
       is(browser.isRemoteBrowser, endProcessIsRemote, "Should have switched to the right process synchronously");
     }
     await docLoadedPromise;
 
     is(browser.currentURI.spec, endURL, "Should have made it to the final URL");
     is(browser.isRemoteBrowser, endProcessIsRemote, "Should be displayed in the right process");
   }
--- a/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/Buttons.jsm
+++ b/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/Buttons.jsm
@@ -14,45 +14,45 @@ Cu.import("resource://gre/modules/Servic
 this.Buttons = {
 
   init(libDir) {
     createWidget();
   },
 
   configurations: {
     navBarButtons: {
-      applyConfig: Task.async(() => {
+      applyConfig: async () => {
         CustomizableUI.addWidgetToArea("screenshot-widget", CustomizableUI.AREA_NAVBAR);
-      }),
+      },
     },
 
     tabsToolbarButtons: {
-      applyConfig: Task.async(() => {
+      applyConfig: async () => {
         CustomizableUI.addWidgetToArea("screenshot-widget", CustomizableUI.AREA_TABSTRIP);
-      }),
+      },
     },
 
     menuPanelButtons: {
-      applyConfig: Task.async(() => {
+      applyConfig: async () => {
         CustomizableUI.addWidgetToArea("screenshot-widget", CustomizableUI.AREA_PANEL);
-      }),
+      },
 
       verifyConfig() {
         let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
         if (browserWindow.PanelUI.panel.state == "closed") {
           return Promise.reject("The button isn't shown when the panel isn't open.");
         }
         return Promise.resolve("menuPanelButtons.verifyConfig");
       },
     },
 
     custPaletteButtons: {
-      applyConfig: Task.async(() => {
+      applyConfig: async () => {
         CustomizableUI.removeWidgetFromArea("screenshot-widget");
-      }),
+      },
 
       verifyConfig() {
         let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
         if (browserWindow.document.documentElement.getAttribute("customizing") != "true") {
           return Promise.reject("The button isn't shown when we're not in customize mode.");
         }
         return Promise.resolve("custPaletteButtons.verifyConfig");
       },
--- a/toolkit/.eslintrc.js
+++ b/toolkit/.eslintrc.js
@@ -4,10 +4,12 @@ module.exports = {
   extends: [
     "plugin:mozilla/recommended"
   ],
 
   rules: {
     // XXX Bug 1326071 - This should be reduced down - probably to 20 or to
     // be removed & synced with the mozilla/recommended value.
     "complexity": ["error", 41],
+
+    "mozilla/no-task": "error",
   }
 };
--- a/toolkit/components/thumbnails/test/browser_thumbnails_storage.js
+++ b/toolkit/components/thumbnails/test/browser_thumbnails_storage.js
@@ -13,70 +13,70 @@ XPCOMUtils.defineLazyGetter(this, "Sanit
 });
 
 /**
  * These tests ensure that the thumbnail storage is working as intended.
  * Newly captured thumbnails should be saved as files and they should as well
  * be removed when the user sanitizes their history.
  */
 function* runTests() {
-  yield Task.spawn(function*() {
+  yield (async function() {
     dontExpireThumbnailURLs([URL, URL_COPY]);
 
-    yield promiseClearHistory();
-    yield promiseAddVisitsAndRepopulateNewTabLinks(URL);
-    yield promiseCreateThumbnail();
+    await promiseClearHistory();
+    await promiseAddVisitsAndRepopulateNewTabLinks(URL);
+    await promiseCreateThumbnail();
 
     // Make sure Storage.copy() updates an existing file.
-    yield PageThumbsStorage.copy(URL, URL_COPY);
+    await PageThumbsStorage.copy(URL, URL_COPY);
     let copy = new FileUtils.File(PageThumbsStorage.getFilePathForURL(URL_COPY));
     let mtime = copy.lastModifiedTime -= 60;
 
-    yield PageThumbsStorage.copy(URL, URL_COPY);
+    await PageThumbsStorage.copy(URL, URL_COPY);
     isnot(new FileUtils.File(PageThumbsStorage.getFilePathForURL(URL_COPY)).lastModifiedTime, mtime,
           "thumbnail file was updated");
 
     let file = new FileUtils.File(PageThumbsStorage.getFilePathForURL(URL));
     let fileCopy = new FileUtils.File(PageThumbsStorage.getFilePathForURL(URL_COPY));
 
     // Clear the browser history. Retry until the files are gone because Windows
     // locks them sometimes.
     info("Clearing history");
     while (file.exists() || fileCopy.exists()) {
-      yield promiseClearHistory();
+      await promiseClearHistory();
     }
     info("History is clear");
 
     info("Repopulating");
-    yield promiseAddVisitsAndRepopulateNewTabLinks(URL);
-    yield promiseCreateThumbnail();
+    await promiseAddVisitsAndRepopulateNewTabLinks(URL);
+    await promiseCreateThumbnail();
 
     info("Clearing the last 10 minutes of browsing history");
     // Clear the last 10 minutes of browsing history.
-    yield promiseClearHistory(true);
+    await promiseClearHistory(true);
 
     info("Attempt to clear file");
     // Retry until the file is gone because Windows locks it sometimes.
-    yield promiseClearFile(file, URL);
+    await promiseClearFile(file, URL);
 
     info("Done");
-  });
+  })();
 }
 
-var promiseClearFile = Task.async(function*(aFile, aURL) {
+async function promiseClearFile(aFile, aURL) {
   if (!aFile.exists()) {
     return undefined;
   }
   // Re-add our URL to the history so that history observer's onDeleteURI()
   // is called again.
-  yield PlacesTestUtils.addVisits(makeURI(aURL));
-  yield promiseClearHistory(true);
+  await PlacesTestUtils.addVisits(makeURI(aURL));
+  await promiseClearHistory(true);
   // Then retry.
   return promiseClearFile(aFile, aURL);
-});
+}
 
 function promiseClearHistory(aUseRange) {
   let s = new Sanitizer();
   s.prefDomain = "privacy.cpd.";
 
   let prefs = gPrefService.getBranch(s.prefDomain);
   prefs.setBoolPref("history", true);
   prefs.setBoolPref("downloads", false);
--- a/toolkit/modules/Sqlite.jsm
+++ b/toolkit/modules/Sqlite.jsm
@@ -587,17 +587,17 @@ ConnectionData.prototype = Object.freeze
               throw ex;
             }
           }
 
           let result;
           try {
             // Keep Task.spawn here to preserve API compat; unfortunately
             // func was a generator rather than a task here.
-            result = await Task.spawn(func);
+            result = await Task.spawn(func); // eslint-disable-line mozilla/no-task
           } catch (ex) {
             // It's possible that the exception has been caused by trying to
             // close the connection in the middle of a transaction.
             if (this._closeRequested) {
               this._log.warn("Connection closed while performing a transaction", ex);
             } else {
               this._log.warn("Error during transaction. Rolling back", ex);
               // If we began a transaction, we must rollback it.
--- a/toolkit/modules/Task.jsm
+++ b/toolkit/modules/Task.jsm
@@ -1,16 +1,18 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80 filetype=javascript: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
+/* eslint-disable mozilla/no-task */
+
 this.EXPORTED_SYMBOLS = [
   "Task"
 ];
 
 /**
  * This module implements a subset of "Task.js" <http://taskjs.org/>.
  *
  * Paraphrasing from the Task.js site, tasks make sequential, asynchronous
--- a/toolkit/modules/tests/xpcshell/test_Promise.js
+++ b/toolkit/modules/tests/xpcshell/test_Promise.js
@@ -545,17 +545,17 @@ tests.push(
         do_check_eq(result, RESULT, "Promise.resolve propagated the correct result");
       }
     );
   }));
 
 // Test that Promise.resolve throws when its argument is an async function.
 tests.push(
   make_promise_test(function test_promise_resolve_throws_with_async_function(test) {
-    Assert.throws(() => Promise.resolve(Task.async(function* () {})),
+    Assert.throws(() => Promise.resolve(Task.async(function* () {})), // eslint-disable-line mozilla/no-task
                   /Cannot resolve a promise with an async function/);
     return Promise.resolve();
   }));
 
 // Test that the code after "then" is always executed before the callbacks
 tests.push(
   make_promise_test(function then_returns_before_callbacks(test) {
     let promise = Promise.resolve();
--- a/tools/lint/eslint/eslint-plugin-mozilla/lib/index.js
+++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/index.js
@@ -41,16 +41,17 @@ module.exports = {
     "import-globals": require("../lib/rules/import-globals"),
     "import-headjs-globals": require("../lib/rules/import-headjs-globals"),
     "mark-test-function-used": require("../lib/rules/mark-test-function-used"),
     "no-aArgs": require("../lib/rules/no-aArgs"),
     "no-cpows-in-tests": require("../lib/rules/no-cpows-in-tests"),
     "no-single-arg-cu-import": require("../lib/rules/no-single-arg-cu-import"),
     "no-import-into-var-and-global":
       require("../lib/rules/no-import-into-var-and-global.js"),
+    "no-task": require("../lib/rules/no-task"),
     "no-useless-parameters": require("../lib/rules/no-useless-parameters"),
     "no-useless-removeEventListener":
       require("../lib/rules/no-useless-removeEventListener"),
     "reject-importGlobalProperties":
       require("../lib/rules/reject-importGlobalProperties"),
     "reject-some-requires": require("../lib/rules/reject-some-requires"),
     "use-default-preference-values":
       require("../lib/rules/use-default-preference-values"),
@@ -65,16 +66,17 @@ module.exports = {
     "import-content-task-globals": "off",
     "import-globals": "off",
     "import-headjs-globals": "off",
     "mark-test-function-used": "off",
     "no-aArgs": "off",
     "no-cpows-in-tests": "off",
     "no-single-arg-cu-import": "off",
     "no-import-into-var-and-global": "off",
+    "no-task": "off",
     "no-useless-parameters": "off",
     "no-useless-removeEventListener": "off",
     "reject-importGlobalProperties": "off",
     "reject-some-requires": "off",
     "use-default-preference-values": "off",
     "use-ownerGlobal": "off",
     "var-only-at-top-level": "off"
   }
new file mode 100644
--- /dev/null
+++ b/tools/lint/eslint/eslint-plugin-mozilla/lib/rules/no-task.js
@@ -0,0 +1,31 @@
+/**
+ * @fileoverview Reject common XPCOM methods called with useless optional
+ *               parameters, or non-existent parameters.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+"use strict";
+
+// -----------------------------------------------------------------------------
+// Rule Definition
+// -----------------------------------------------------------------------------
+
+module.exports = function(context) {
+  // ---------------------------------------------------------------------------
+  // Public
+  //  --------------------------------------------------------------------------
+
+  return {
+    "CallExpression": function(node) {
+      let callee = node.callee;
+      if (callee.type === "MemberExpression" &&
+          callee.object.type === "Identifier" &&
+          callee.object.name === "Task") {
+        context.report({node, message: "Task.jsm is deprecated."});
+      }
+    }
+  };
+};