Bug 1768031 - Reject top-level await in modules via an ESLint rule. r=Gijs

Differential Revision: https://phabricator.services.mozilla.com/D145892
This commit is contained in:
Mark Banner 2022-05-11 14:08:15 +00:00
parent 3dde0f67c2
commit 889c6efaf2
8 changed files with 109 additions and 2 deletions

View file

@ -54,6 +54,7 @@ The plugin implements the following rules:
eslint-plugin-mozilla/reject-requires-await
eslint-plugin-mozilla/reject-scriptableunicodeconverter
eslint-plugin-mozilla/reject-some-requires
eslint-plugin-mozilla/reject-top-level-await
eslint-plugin-mozilla/use-cc-etc
eslint-plugin-mozilla/use-chromeutils-generateqi
eslint-plugin-mozilla/use-chromeutils-import

View file

@ -0,0 +1,26 @@
reject-top-level-await
======================
Rejects ``await`` at the top-level of code in modules. Top-level ``await`` is
not currently support in Gecko's component modules, so this is rejected.
Examples of incorrect code for this rule:
-----------------------------------------
.. code-block:: js
await foo;
if (expr) {
await foo;
}
for await (let x of [1, 2, 3]) { }
Examples of correct code for this rule:
---------------------------------------
.. code-block:: js
async function() { await foo; }
async function() { for await (let x of [1, 2, 3]) { } }

View file

@ -49,6 +49,7 @@ module.exports = {
},
files: ["**/*.mjs", "**/*.jsm", "**/*.jsm.js"],
rules: {
"mozilla/reject-top-level-await": "error",
// Bug 1703953: We don't have a good way to check a file runs in a
// privilieged context. Apply this for jsm files as we know those are
// privilieged, and then include more directories elsewhere.

View file

@ -59,6 +59,7 @@ module.exports = {
"reject-scriptableunicodeconverter": require("../lib/rules/reject-scriptableunicodeconverter"),
"reject-relative-requires": require("../lib/rules/reject-relative-requires"),
"reject-some-requires": require("../lib/rules/reject-some-requires"),
"reject-top-level-await": require("../lib/rules/reject-top-level-await"),
"rejects-requires-await": require("../lib/rules/rejects-requires-await"),
"use-cc-etc": require("../lib/rules/use-cc-etc"),
"use-chromeutils-generateqi": require("../lib/rules/use-chromeutils-generateqi"),

View file

@ -0,0 +1,42 @@
/**
* @fileoverview Don't allow only() in tests
*
* 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";
var helpers = require("../helpers");
module.exports = {
meta: {
docs: {
url:
"https://firefox-source-docs.mozilla.org/code-quality/lint/linters/eslint-plugin-mozilla/reject-top-level-await.html",
},
messages: {
rejectTopLevelAwait:
"Top-level await is not currently supported in component files.",
},
type: "problem",
},
create(context) {
return {
AwaitExpression(node) {
if (!helpers.getIsGlobalScope(context.getAncestors())) {
return;
}
context.report({ node, messageId: "rejectTopLevelAwait" });
},
ForOfStatement(node) {
if (!node.await || !helpers.getIsGlobalScope(context.getAncestors())) {
return;
}
context.report({ node, messageId: "rejectTopLevelAwait" });
},
};
},
};

View file

@ -1,6 +1,6 @@
{
"name": "eslint-plugin-mozilla",
"version": "2.12.2",
"version": "2.12.3",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View file

@ -1,6 +1,6 @@
{
"name": "eslint-plugin-mozilla",
"version": "2.12.2",
"version": "2.12.3",
"description": "A collection of rules that help enforce JavaScript coding standard in the Mozilla project.",
"keywords": [
"eslint",

View file

@ -0,0 +1,36 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------
var rule = require("../lib/rules/reject-top-level-await");
var RuleTester = require("eslint").RuleTester;
const ruleTester = new RuleTester({
parserOptions: { ecmaVersion: 13, sourceType: "module" },
});
// ------------------------------------------------------------------------------
// Tests
// ------------------------------------------------------------------------------
function invalidCode(code, messageId) {
return { code, errors: [{ messageId: "rejectTopLevelAwait" }] };
}
ruleTester.run("reject-top-level-await", rule, {
valid: [
"async() => { await bar() }",
"async() => { for await (let x of []) {} }",
],
invalid: [
invalidCode("await foo"),
invalidCode("{ await foo }"),
invalidCode("(await foo)"),
invalidCode("for await (let x of []) {}"),
],
});